最近做 vue2 项目,用到了 element-ui,发现 element-ui 的表格组件用起来不是很方便,每列都要写一大堆代码,于是就想着封装一个表格组件,支持一键配置表格项,这样就可以减少很多重复代码。
一、看组件效果
原本的 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 基本思路
EnhancedElTable组件接收data和columns两个props,data是表格数据,columns是表格列配置。- 在组件中遍历
columns,根据配置生成对应的表格列项 columns可以配置fixed,width,label,prop等属性,这些属性会直接传递给el-table-column组件。columns中的配置项,可以配置slotName,用于指定插槽的名称,这样就可以在组件外部定义插槽内容。columns中的配置项,可以配置component,用于指定自定义组件,这样就可以使用自定义组件来渲染表格列项。
2.2 实现逻辑
新建 EnhancedElTable.vue 组件,接收 data 和 columns 两个 props,data 是表格数据,columns 是列项配置。在组件中遍历 columns,根据配置生成对应的列项。
2.3 基础实现
先不考虑复杂的情况,
表格其他属性和事件用v-bind和v-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,用于指定插槽的名称,这样就可以在组件外部定义插槽内容。