项目开发中,有时候需要实现单元格合并的需求,这里记录一下在Ant Design Vue的实现。
<template>
<div>
<a-table bordered :data-source="dataSource" :columns="columns"></a-table>
</div>
</template>
<script>
const dataSource = [
{ key: '1', school: '林州一中', grade: '高一', class: '二班', name: '徐强' },
{ key: '2', school: '林州一中', grade: '高一', class: '一班', name: '林东'},
{ key: '3', school: '林州一中', grade: '高一', class: '二班', name: '李丹'},
{ key: '4', school: '林州一中', grade: '高二', class: '二班', name: '刘康'},
{ key: '5', school: '实验高中', grade: '高三', class: '二班', name: '杨江'},
{ key: '6', school: '实验高中', grade: '高三', class: '一班', name: '陈锋'},
{ key: '7', school: '实验高中', grade: '高三', class: '二班', name: '李华'},
{ key: '8', school: '实验高中', grade: '高四', class: '二班', name: '赵铭'}
]
const columns = [
{
title: '学校', dataIndex: 'school', width: '25%',
align: 'center', key: 'school',
customRender (_, row) {
return {
children: row.school,
attrs: {
rowSpan: row.schoolRowSpan
}
}
}
},
{
title: '年级', dataIndex: 'grade', width: '25%',
scopedSlots: { customRender: 'grade' }, align: 'center', key: 'grade',
customRender (_, row) {
return {
children: row.grade,
attrs: {
rowSpan: row.gradeRowSpan
}
}
}
},
{
title: '班级', dataIndex: 'class', width: '25%',
scopedSlots: { customRender: 'class' }, align: 'center'
},
{
title: '姓名', dataIndex: 'name', width: '25%',
scopedSlots: { customRender: 'name' }, align: 'center'
}
]
export default {
name: 'TableMerge',
data () {
return {
dataSource,
columns
}
},
methods: {
// 合并单元格
rowSpan (key, data) {
const arr = data
.reduce((result, item) => {
if (result.indexOf(item[key]) < 0) {
result.push(item[key])
}
return result
}, [])
.reduce((result, keys) => {
const children = data.filter(item => item[key] === keys)
result = result.concat(
children.map((item, index) => ({
...item,
[`${key}RowSpan`]: index === 0 ? children.length : 0
}))
)
return result
}, [])
return arr
},
// 表格合并
mergeRowCell (data) {
let tableData = this.rowSpan('school', data) //合并学校
tableData = this.rowSpan('grade', tableData) //合并年级
this.dataSource = tableData
}
},
mounted () {
this.mergeRowCell(this.dataSource)
}
}
</script>
合并后: