1.1.1 • Published 4 years ago

@mecc/table v1.1.1

Weekly downloads
-
License
MIT
Repository
github
Last release
4 years ago

@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} /> ,需注意:直接使用的优先级高于全局配置

参数数据类型默认值可选值说明
colAlignStringcenterleft/right/center设置表格列的对齐方式
colHeaderAlignStringcenterleft/right/center设置表头的对其方式
colEmptyTextString'-'-表格单元数据为空时显示的文本内容
pagerOffsetNumber0-设置分页器与表格的间距,单位是'px'
customClassNameString''-自定义class名称
tablePaddingNumber0-Table的Padding值,计算表格高度会用
colShowOverflowTooltipBooleanfalsetrue/false当内容过长被隐藏时显示 tooltip

Table Attributes 表格属性

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

参数数据类型是否必须默认值可选值说明
dataArray--表格数据
columnArray--表格列配置项,具体内容见下方说明
paginationBooleanfalse-是否显示分页器
pagerOffsetNumber0-设置分页器与表格的间距,单位是'px'
colAlignStringcenterleft/right/center设置表格列的对齐方式
colHeaderAlignStringcenterleft/right/center设置表头的对其方式
colEmptyTextString'-'-表格单元数据为空时显示的文本内容
customClassNameString--自定义class名称
tablePaddingNumber0-Table的Padding值,计算表格高度会用
colShowOverflowTooltipBooleanfalsetrue/false当内容过长被隐藏时显示 tooltip

Table Events 表格事件

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

事件名说明参数
page-change同 el-pagination 的 current-changecurrentPage
table-current-change同 el-table 的 current-changecurrentRow, 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

参数数据类型是否必须说明
propString设置表格列的对齐方式
labelString设置表头的对其方式
renderFunction(h, context)/VNode自定义渲染内容,可选返回VNode
formatterFunction(row, column, index)/String自定义渲染内容,可选返回字符串
showFunction()/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>
1.1.1

4 years ago

1.1.0

4 years ago

1.0.7

4 years ago

1.0.6

4 years ago

1.0.5

4 years ago

1.0.4

4 years ago

1.0.2

4 years ago

1.0.3

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago