【需求】
这次的表格需要实现行列合并,并且要在合并后的 td 中使用子组件或弹出弹窗,难点在于:
1. 根据提供的data,自行判断是否合并项的 getRowspan方法
2. customCell 、scopedSlots 冲突导致的子组件无法展示
(在最下方的参考资料中提供了关于这两个难点的解决方法,感谢两位作者。)
【template】
<template>
<div style="margin: 20px;">
<a-table :columns="columns" :data-source="data" bordered>
<template slot="head3" slot-scope="text"><editable-cell :text="text" /></template>
<template slot="func4" slot-scope="text, record">
<a-button v-if="record.func4.length == 0" type="link" @click="handleChoose(record.key)">
<span>请选择item</span>
</a-button>
<a-tooltip v-else placement="topLeft">
<template slot="title">
<span style="margin-right: 8px;" v-for="item in record.func4" :key="item">{{ item }}</span>
</template>
<a-button type="link" @click="handleChoose(record.key)">
<span>已选择{{ record.func4.length }}项</span>
</a-button>
</a-tooltip>
</template>
<template slot="head5" slot-scope="text, record">
<div v-if="record.slot5.isEdit">
<editable-cell :text="record.slot5.value" />
</div>
<div v-else>
{{ record.slot5.value }}
</div>
</template>
<template slot="slot6" slot-scope="text">
<editable-cell :text="text" />
</template>
<template slot="action" slot-scope="text,record">
<div>
<a-button type="link">link {{ record.key }}</a-button>
</div>
</template>
</a-table>
</div>
</template>
【script】
<script>
import EditableCell from '@/components/EditableCell';
const data = [
{
key: '1',
name1: 'item1.1',
name2: 'text1',
slot3: 'slot1',
func4: [],
slot5: {
isEdit: false,
value: 'text'
},
slot6: 'slot',
head7: 'text',
},
{
key: '2',
name1: 'item1.1',
name2: 'text1',
slot3: 'slot1',
func4: [],
slot5: {
isEdit: false,
value: 'text'
},
slot6: 'slot',
head7: 'text',
},
{
key: '3',
name1: 'item2.1',
name2: 'text2',
slot3: 'slot2',
func4: ['item1', 'item2', 'item3'],
slot5: {
isEdit: false,
value: 'text'
},
slot6: 'slot',
head7: 'text',
},
{
key: '4',
name1: 'item2.1',
name2: 'text2',
slot3: 'slot2',
func4: ['item1', 'item2', 'item3'],
slot5: {
isEdit: true,
value: 'slot'
},
slot6: 'slot',
head7: 'text',
},
];
export default {
components: { EditableCell },
data() {
return {
data,
columns: [
{
title: 'head1',
dataIndex: 'name1',
width: 160,
customCell: (record, rowIndex, column) => {
return {
style: { display: this.rowSpanArr[rowIndex] === 0 ? 'none' : undefined },
attrs: {
rowSpan: this.rowSpanArr[rowIndex],
}
}
},
},
{
title: 'head2',
dataIndex: 'name2',
width: 120,
customCell: (record, rowIndex, column) => {
return {
style: { display: this.rowSpanArr[rowIndex] === 0 ? 'none' : undefined },
attrs: {
rowSpan: this.rowSpanArr[rowIndex],
}
}
},
},
{
title: 'head3-slot',
width: 200,
dataIndex: 'slot3',
scopedSlots: { customRender: 'head3' },
customCell: (record, rowIndex, column) => {
return {
style: { display: this.rowSpanArr[rowIndex] === 0 ? 'none' : undefined },
attrs: {
rowSpan: this.rowSpanArr[rowIndex],
}
}
},
},
{
title: 'head4-func',
dataIndex: 'func4',
scopedSlots: { customRender: 'func4' },
customCell: (record, rowIndex, column) => {
return {
style: { display: this.rowSpanArr[rowIndex] === 0 ? 'none' : undefined },
attrs: {
rowSpan: this.rowSpanArr[rowIndex],
}
}
},
},
{
title: 'head5-slot-text',
dataIndex: 'dataCenter',
scopedSlots: { customRender: 'head5' },
},
{
title: 'head6',
dataIndex: 'slot6',
scopedSlots: { customRender: 'slot6' },
},
{
title: 'head7',
dataIndex: 'head7',
},
{
title: 'action',
dataIndex: 'action',
width: 100,
scopedSlots: { customRender: 'action' }
},
],
rowSpanArr: [],
};
},
computed: {},
mounted() {
this.rowSpanArr = this.getRowspan(this.data, 'name1') // 关键句,选一个会重复并且多项会一致的属性如 name1,作为判断是否合并的依据
},
watch: {
},
methods: {
handleChoose(id) {
console.log('请选择项,id:', id);
},
getRowspan(dataScroce, filed) {
let spanArr = [];
let position = 0;
dataScroce.forEach((item, index) => {
if (index === 0) {
spanArr.push(1);
position = 0;
} else {
//需要合并的地方判断
if (dataScroce[index][filed] === dataScroce[index - 1][filed]) {
spanArr[position] += 1;
spanArr.push(0);
} else {
spanArr.push(1);
position = index;
}
}
});
return spanArr
}
}
};
</script>
【注】
import EditableCell from '@/components/EditableCell';
这个子组件是用官网的可编辑单元格这部分改的,链接:表格 Table - Ant Design Vue (antdv.com)
【参考资料】
Ant Design Vue实现a-table表格单元格合并(列/行合并)_a-table合并单元格-CSDN博客
antd的a-table表格中合并且使用插槽(使用customRender合并出现问题解决方案)_a-table customrender-CSDN博客