npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mecc/table

v1.1.1

Published

Advanced vue table component based on el-table.

Downloads

8

Readme

@mecc/table

Intro 简介

@mecc/table 是一款表格组件,基于 vueelement-ui 进行的二次封装,无需繁琐的模板代码,所有的表格列配置项均可通过属性传递,使你的代码更干净。

Feature 特色

  • @mecc/table 通过 column 属性来实现表格列的配置,灵活的 JSX 语法便于高度自定义表格组件;

  • @mecc/table 采用 $attrs$listeners 接收参数和监听事件,无缝对接 element-ui 中的 Table 文档板块,包含自定义 slot 插槽,上手更快;

  • column 每列配置,最低限度仅传递 proplabel 属性,就可实现标准值输出,也可以使用 formatterrender 属性进行格式化输出;

Install 安装

  • 通过 npm 或者 yarn 安装项目
npm i @mecc/table
# 或者
yarn add @mecc/table
  • 引用组件,根据需要可全局引入或者局部引入
// 组件依赖 vue 和 element-ui

// 全局引入
// >>> main.js
import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/libs/theme-chalk/index.css'

import MeccTable from '@mecc/table'
Vue.use(MeccTable, options)  // @mecc/table 全局引用时可传入配置项,具体内容见下方

// 局部引入
// >>> Demo.vue
<script>
import MeccTable from '@mecc/table'
export default {
    components: {
        MeccTable
    }
}
</script>

Options 配置项

配置项内容可在全局引入时设置,或者直接使用 <mecc-table {...options} /> ,需注意:直接使用的优先级高于全局配置

| 参数 | 数据类型 | 默认值 | 可选值 | 说明 | |:----------------------:|:--------:|:------:|:-----------------:|:----------------------------------:| | colAlign | String | center | left/right/center | 设置表格列的对齐方式 | | colHeaderAlign | String | center | left/right/center | 设置表头的对其方式 | | colEmptyText | String | '-' | - | 表格单元数据为空时显示的文本内容 | | pagerOffset | Number | 0 | - | 设置分页器与表格的间距,单位是'px' | | customClassName | String | '' | - | 自定义class名称 | | tablePadding | Number | 0 | - | Table的Padding值,计算表格高度会用 | | colShowOverflowTooltip | Boolean | false | true/false | 当内容过长被隐藏时显示 tooltip |

Table Attributes 表格属性

仅展示必填项和新增项,其余参数见 Element Doc Table #Table-column AttributesElement Doc Pagination

| 参数 | 数据类型 | 是否必须 | 默认值 | 可选值 | 说明 | |:----------------------:|:--------:|:--------:|:------:|:-----------------:|:----------------------------------:| | data | Array | 是 | - | - | 表格数据 | | column | Array | 是 | - | - | 表格列配置项,具体内容见下方说明 | | pagination | Boolean | 否 | false | - | 是否显示分页器 | | pagerOffset | Number | 否 | 0 | - | 设置分页器与表格的间距,单位是'px' | | colAlign | String | 否 | center | left/right/center | 设置表格列的对齐方式 | | colHeaderAlign | String | 否 | center | left/right/center | 设置表头的对其方式 | | colEmptyText | String | 否 | '-' | - | 表格单元数据为空时显示的文本内容 | | customClassName | String | 否 | - | - | 自定义class名称 | | tablePadding | Number | 否 | 0 | - | Table的Padding值,计算表格高度会用 | | colShowOverflowTooltip | Boolean | 否 | false | true/false | 当内容过长被隐藏时显示 tooltip |

Table Events 表格事件

仅展示新增事件,其余事件见 Element Doc Table #Table EventsElement Doc Pagination

| 事件名 | 说明 | 参数 | |:--------------------:|:----------------------------------:|:-------------------------:| | page-change | 同 el-pagination 的 current-change | currentPage | | table-current-change | 同 el-table 的 current-change | currentRow, oldCurrentRow |

Table Methods 表格方法

支持全部 el-tableel-pagination 方法,详见 Element Doc Table #Table MethodsElement Doc Pagination

Table Slot 表格插槽

| name | 说明 | |:----------:|:------------------------------------------------------------------------:| | append | 插入至表格最后一行之后的内容。若表格有合计行,该 slot 会位于合计行之上。 | | empty | 空数据时显示的文本内容。 | | pagination | 分页器中的自定义内容,需要在 layout 中列出 slot |

Column 列配置项

仅展示必填项和新增项,其余参数见 Element Doc Table #Table-column Attributes

| 参数 | 数据类型 | 是否必须 | 说明 | |:---------:|:-----------------------------------:|:--------:|:------------------------------:| | prop | String | 是 | 设置表格列的对齐方式 | | label | String | 是 | 设置表头的对其方式 | | render | Function(h, context)/VNode | 否 | 自定义渲染内容,可选返回VNode | | formatter | Function(row, column, index)/String | 否 | 自定义渲染内容,可选返回字符串 | | show | Function()/Boolean | 否 | 是否渲染该列,默认渲染 |

Usage Example 使用示例

  • 所有 <el-table> 接受的属性和事件, <mecc-table> 都接受
  • 由于 <el-table><el-pagination> 同时存在事件 @current-change , 建议使用 @table-current-change 和 @page-change 区分
  • <mecc-table> 接受一些新属性,见配置清单
  • <mecc-table> 中实现了 <el-table><el-pagination> 的所有 <slot>
  • 需要注意:<el-pagination> 的自定义插槽在 <mecc-table> 中为 <slot name="pagination">
<template>
  <mecc-table
    :data="dataList"
    :column="column"
    stripe
    layout="slot, -> , prev, pager, next, jumper, sizes, total"
    :pagination="total / pageSize > 1"
    :total="total"
    :current-page.sync="currentPage"
    :page-size="pageSize"
    highlight-current-row
    hide-on-single-page
    col-align="center"
    col-header-align="left"
    @page-change="handlePageChange"
    @size-change="handleSizeChange"
    @table-current-change="handleCurrentChange"
  >
    <template #pagination>
      <span>Guess Page Game</span>
    </template>
    <template #empty>
      <span>Guess Page Game</span>
    </template>
  </mecc-table>
</template>

<script>
export default {
  data() {
    return {
      currentPage: 1,
      pageSize: 10,
      customHeader: 'MeccTable',
      cache: {}
    };
  },
  computed: {
    dataList() {
      const res = [];
      for (let idx = 0; idx < 30; idx++) {
        res.push({
          name: 'mecc' + idx,
          // age: idx,
          gender: idx % 2 ? 'male' : 'female',
          hobby: ['html', 'css', 'js'],
          isEdit: false
        });
      }
      return res;
    },
    total() {
      return this.dataList.length;
    },
    column() {
      return [
        {
          prop: 'name',
          label: '姓名'
        },
        {
          prop: 'custom_hidden',
          label: '自定义隐藏',
          show: () => false
        },
        {
          prop: 'age',
          label: '年龄',
          formatter: (row, column, index) => {
            if (row[column.property]) {
              return row[column.property] + '岁';
            }
          },
          renderHeader: (h, ctx) => {
            return <el-input v-model={this.customHeader} size='mini' />;
          }
        },
        {
          prop: 'gender',
          label: '性别',
          render: (h, ctx) => {
            const genderNameMap = { male: '男生', female: '女生' };
            if (ctx.row.gender) {
              return (
                <el-tag
                  type={ctx.row.gender === 'male' ? 'danger' : 'success'}
                  size='mini'
                >
                  {genderNameMap[ctx.row.gender]}
                </el-tag>
              );
            }
          }
        },
        {
          prop: 'hobby',
          label: '兴趣',
          render: (h, ctx) => {
            if (!ctx.row.hobby || !ctx.row.hobby.length) return;

            if (!ctx.row.isEdit) {
              const hobbyList = ctx.row.hobby.map(item => (
                <el-tag size='mini' style='margin-right: 5px;'>
                  {item}
                </el-tag>
              ));
              return <div>{hobbyList}</div>;
            }

            const options = [
              {
                name: '前端',
                id: 'front',
                children: [
                  {
                    name: 'HTML',
                    id: 'html'
                  },
                  {
                    name: 'JavaScript',
                    id: 'js'
                  },
                  {
                    name: 'CSS',
                    id: 'css'
                  }
                ]
              },
              {
                name: '后端',
                id: 'back',
                children: [
                  {
                    name: 'JAVA',
                    id: 'java'
                  },
                  {
                    name: 'Golang',
                    id: 'golang'
                  },
                  {
                    name: 'Python',
                    id: 'python'
                  }
                ]
              }
            ];
            /**
             * 特别注意
             * 由于 el-cascader 需要传递名称为 'props' 的属性
             * 而在 vue 的 JSX 语法解析中,'props' 属性无法正常传递,所以这里需要特殊处理下
             * 详情可参考 https://www.yuque.com/zeka/vue/vu60wg
             */
            const cascaderProps = {
              options,
              props: {
                checkStrictly: true,
                label: 'name',
                value: 'id',
                multiple: true,
                emitPath: false
              },
              clearable: true,
              filterable: true
            };
            return (
              <el-cascader
                {...{ props: cascaderProps }}
                v-model={ctx.row.hobby}
              />
            );
          }
        },
        {
          prop: 'operate',
          label: '操作',
          align: 'center',
          headerAlign: 'center',
          render: (h, ctx) => {
            const handleEdit = () => {
              this.cache[ctx.row.name] = JSON.parse(JSON.stringify(ctx.row));
              ctx.row.isEdit = true;
            };
            const handleCancel = () => {
              Object.assign(ctx.row, this.cache[ctx.row.name]);
              ctx.row.isEdit = false;
            };
            const handleConfirm = () => {
              setTimeout(() => {
                console.log('修改成功');
                ctx.row.isEdit = false;
              });
            };
            if (!ctx.row.isEdit) {
              return (
                <el-button type='primary' size='mini' onClick={handleEdit}>
                  编辑
                </el-button>
              );
            }
            return (
              <el-button-group>
                <el-button type='success' size='mini' onClick={handleConfirm}>
                  保存
                </el-button>
                <el-button type='info' size='mini' onClick={handleCancel}>
                  取消
                </el-button>
              </el-button-group>
            );
          }
        }
      ];
    }
  },
  methods: {
    handleCurrentChange(val, old) {
      console.log('row', val, old);
    },
    handlePageChange(val) {
      console.log('page: ', val);
    },
    handleSizeChange(val) {
      console.log('size: ', val);
      this.pageSize = val;
      this.currentPage = 1;
    }
  }
};
</script>