需求
1.能像iview一样通过配置的方式传参数
2.能复用element-ui中table,el-table-column中的属性和事件
3.给table添加一些默认的属性
<custom-table :columns="columns" :data="data" height="500" border @selection-change="handleSelection" ... />
<script>
export default {
data(){
return {
columns:[
{label:'姓名', prop:'name', width:'60px', },
{label:'地址', prop:'address'},
],
data: [
{name: '张三',address:'xxx'},
{name: '李四',address:'xxx'},
]
}
},
methods:{
handleSelection(val) {
console.log(val);
}
}
}
</scirpt>
技术准备
1.怎么复用el-table的属性和事件呢?
在vue中listeners配合inheritAttrs 这俩个重要的api可以帮助我们最简单的实现属性和事件的在组件中传递
2.在遍历columns中会有很多判断条件,怎么实现多表头?
在这里可以使用jsx, 多表头可以用递归来处理。github.com/vuejs/jsx#i…
3.怎么实现slot header 和 slotScope呢?
可以在columns中使用传一个返回jsx的函数。
最终实现
<script>
export default {
inheritAttrs: false,
name: 'custom-table',
props: {
data: {
type: Array,
},
columns: {
type: Array,
},
},
render() {
function getTableColumn(data) {
const excludeList = ['index', 'expand', 'selection'];
const slots = {};
if (data.headerRender) {
slots.header = () => data.headerRender();
}
if (data.render) {
slots.default = (scope) => data.render(scope);
} else if (excludeList.indexOf(data.type) === -1) {
slots.default = (scope) => scope.row[data.prop] || '--';
}
return (
<el-table-column
align="center"
{...{ attrs: data }}
scopedSlots={slots}>
{
data.children && data.children.map((i) => getTableColumn(i))
}
</el-table-column>
);
}
const tableColumns = this.columns.map(getTableColumn);
return (
<el-table
data={this.data}
ref="table"
tooltip-effect="dark"
stripe
border
{...{ attrs: this.$attrs }}
{...{ on: this.$listeners }}
>
{tableColumns}
</el-table>);
},
};
</script>
具体使用
<template>
<div class="home">
<el-button @click="handleClear">清理</el-button>
<my-table
:columns="columns"
ref="table"
@selection-change="handleSelect"
@sort-change="handleSort"
:data="data">
</my-table>
</div>
</template>
<script>
import MyTable from '@/components/my-table/index.vue';
export default {
name: 'Home',
components: {
MyTable,
},
data() {
return {
columns: [
{ type: 'selection', width: '50px' },
{ type: 'index', width: '50px' },
{ prop: 'name', label: '姓名', align: 'right' },
{ prop: 'sex', label: '性别' },
{ prop: 'age', label: '年龄', align: 'right', sortable: true},
{
prop: 'info',
label: '信息',
children: [
{ prop: 'province', label: '省', align: 'left' },
{ prop: 'city', label: '市', align: 'right' },
],
},
{
label: '操作',
fixed: 'right',
render: ({ row }) => [
<el-button vOn:click={() => this.handleClick(row)}>按钮</el-button>,
<el-button vOn:click={() => this.handleClick(row)}>编辑</el-button>,
],
},
],
data: [
{
name: '姓名', age: 1, sex: '男sddddddddddddad 单算打算多所所得到的多多多多多多多多多多多多多多多多多', city: '北京', province: '北京',
},
{ name: '姓名1', age: 4 },
{ name: '姓名2', age: 3 },
{ name: '姓名2', age: 5 },
{ name: '姓名2', age: 6 },
{ name: '姓名2' },
{ name: '姓名2' },
],
};
},
methods: {
handleClick(row) {
console.log(row);
},
handleSelect(data) {
console.log(data);
},
handleClear() {
console.log(this.$refs.table.$refs.table.clearSelection());
},
handleSort({ column, prop, order }) {
console.log(column);
console.log(prop);
console.log(order);
},
},
};
</script>