element-ui表格组件增强版,支持动态配置

891 阅读5分钟

最近做 vue2 项目,用到了 element-ui,发现 element-ui 的表格组件用起来不是很方便,每列都要写一大堆代码,于是就想着封装一个表格组件,支持一键配置表格项,这样就可以减少很多重复代码。

一、看组件效果

el_table1.png

原本的 el-table,列项代码繁多

实现以上效果,官方文档给出的代码如下:

<template>
  <el-table :data="tableData" border style="width: 100%">
    <el-table-column fixed prop="date" label="日期" width="150">
    </el-table-column>
    <el-table-column prop="name" label="姓名" width="120"> </el-table-column>
    <el-table-column prop="province" label="省份" width="120">
    </el-table-column>
    <el-table-column prop="city" label="市区" width="120"> </el-table-column>
    <el-table-column prop="address" label="地址" width="300"> </el-table-column>
    <el-table-column prop="zip" label="邮编" width="120"> </el-table-column>
    <el-table-column fixed="right" label="操作" width="100">
      <template slot-scope="scope">
        <el-button @click="handleClick(scope.row)" type="text" size="small"
          >查看</el-button
        >
        <el-button type="text" size="small">编辑</el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  methods: {
    handleClick(row) {
      console.log(row);
    },
  },

  data() {
    return {
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1518 弄',
          zip: 200333,
        },
        {
          date: '2016-05-04',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1517 弄',
          zip: 200333,
        },
        {
          date: '2016-05-01',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1519 弄',
          zip: 200333,
        },
        {
          date: '2016-05-03',
          name: '王小虎',
          province: '上海',
          city: '普陀区',
          address: '上海市普陀区金沙江路 1516 弄',
          zip: 200333,
        },
      ],
    };
  },
};
</script>

增强版的 el-table - 去掉列项组件代码,改成 columns 动态配置

增强版的 el-table,只需要配置列项的 columns,就可以实现以上效果,代码如下:

<template>
  <EnhancedElTable
    :data="tableData"
    border
    style="width: 100%"
    :columns="columns"
  >
    <template v-slot:operation="{ row }">
      <el-button @click="handleClick(row)" type="text" size="small"
        >查看</el-button
      >
      <el-button type="text" size="small">编辑</el-button>
    </template>
  </EnhancedElTable>
</template>
<script>
export default {
  data() {
    return {
      columns: [
        {
          fixed: true,
          prop: 'date',
          label: '日期',
          width: 150,
        },
        {
          prop: 'name',
          label: '姓名',
          width: 120,
        },
        {
          prop: 'province',
          label: '省份',
          width: 120,
        },
        {
          prop: 'city',
          label: '市区',
          width: 120,
        },
        {
          prop: 'address',
          label: '地址',
          width: 300,
        },
        {
          prop: 'zip',
          label: '邮编',
          width: 120,
        },
        {
          fixed: 'right',
          label: '操作',
          width: 100,
          slotName: 'operation',
        },
      ],
      // 其他不变
    };
  },
  methods: {
    // ...不变
  },
};
</script>

二、EnhancedElTable组件实现

2.1 基本思路

  1. EnhancedElTable 组件接收 datacolumns 两个 propsdata 是表格数据,columns 是表格列配置。
  2. 在组件中遍历 columns,根据配置生成对应的表格列项
  3. columns 可以配置 fixedwidthlabelprop 等属性,这些属性会直接传递给 el-table-column 组件。
  4. columns 中的配置项,可以配置 slotName,用于指定插槽的名称,这样就可以在组件外部定义插槽内容。
  5. columns 中的配置项,可以配置 component,用于指定自定义组件,这样就可以使用自定义组件来渲染表格列项。

2.2 实现逻辑

新建 EnhancedElTable.vue 组件,接收 datacolumns 两个 propsdata 是表格数据,columns 是列项配置。在组件中遍历 columns,根据配置生成对应的列项。

2.3 基础实现

先不考虑复杂的情况,
表格其他属性和事件用v-bindv-on直接传递给 el-table 组件。
data 直接放在 table 上,columns 遍历生成每个表单项。
列项都是el-table-column,只是内部有所区分,其配置项直接传递给 el-table-column 组件。

所以 EnhancedElTable.vue 组件如下:

<template>
  <el-table :data="data" v-bind="$attrs" v-on="$listeners">
    <el-table-column
      v-for="column in columns"
      :key="column.prop || column.label"
      v-bind="column"
    >
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  name: 'EnhancedElTable',
  props: {
    data: {
      type: Array,
      default() {
        return [];
      },
    },
    columns: {
      type: Array,
      default() {
        return [];
      },
    },
  },
};
</script>

2.4 增加 自定义插槽

对于一些特殊的列项,比如操作列,需要自定义渲染,这时候需要使用 slot 插槽。
columns 中配置 slotName,用于指定插槽的名称,这样就可以在组件外部定义插槽内容。