Element UI
动态生成多级表头
思路:使用事先定义好的表头数据结构,使用
Vue
组件中的render
函数动态渲染
1、表头数据结构
可以看出,下面的数据结构可以描述多级表头的包含关系,其中
name
表示列的lable
,prop
就是后端传过来的属性,width
对应列宽,exeFun
函数代表了当前列的值获取方式,不定义则直接获取原始值。child
属性是子表头,可无限扩展。
revealList: [
{
name: '性别',
prop: 'gender',
width: 100,
exeFun: row => this.enums.gender.filter(e => e.value === row.gender).map(e => e.label)[0]
},
{
name: '专业技能',
child: [
{
name: '前端',
child: [
{
name: 'JavaScript',
prop: 'js'
}
]
},
{
name: '后端',
child: [
{
name: 'java',
child: [
{
name: 'nio',
prop: 'nio'
},
]
},
{
name: '框架',
child: [
{
name: 'SpringBoot',
prop: 'springboot'
}
]
}
]
},
]
},
],
2、定义组件
使用
render
函数,对上面定义的表头数据进行递归渲染
Vue.component('my-col', {
render(h) {
return this.render(h, this.col)
},
props: {
col: {}
},
data: function () {
return {}
},
methods: {
render(h, header) {
let column = [];
// 如果表头还有子表头
if (header.child) {
let child = [];
for (let i = 0; i < header.child.length; i++) {
// 递归渲染
child.push(this.render(h, header.child[i]))
}
column.push(h('el-table-column', {
props: {
label: header.name,
align: 'center',
}
}, child))
} else {
column.push(h('el-table-column', {
props: {
// 可以自己追加其他el-table-colum支持的参数
label: header.name,
prop: header.prop,
width: header.width,
align: 'center',
},
scopedSlots: {
default: scope => {
let value;
// 有exeFun优先执行
if (header.exeFun) {
value = header.exeFun(scope.row)
} else {
value = scope.row[header.prop]
}
return h('span', value)
}
}
}))
}
return column
},
}
});
3、使用方式
html
<el-table :data="list" style="width: 100%" size="mini">
<my-col v-for="(item, index) in revealList" :col="item" :key="index" :prop="item.prop" :label="item.name"> </my-col>
</el-table>
-
vue
const app = new Vue({ el: "#app", data() { return { enums: { gender: [ { label: '男', value: '1' }, { label: '女', value: '2' }, ] }, list: [ { gender: '1', js: '熟练', nio: '了解', basic: '精通', springboot: '熟练' }, ], revealList: [ //...省略 ], } }, methods: {} })
其他
这种方式只能应对简单的表格渲染,不能应对需要内嵌组件的方式,所以没有直接定义一个table
组件替代el-table
,所以在有这种需求的时候自己写el-table-column
。