功能需求:
使用Ant Design vue 中的table和vue3实现第一列动态合并相同数据,第二列以树形展开
需要达到效果图:
实现过程:
实现该需求还是挺麻烦的,查了好久网上的资料没有发现和我一样的需求实现,然后请教了其他前端大神,也试了好些时间才实现,特此记录一下,以便下次好找。
实现代码:
表格渲染
<a-table class="mt_20" :columns="rightColumns" :expandIconColumnIndex="1" :rowKey="(record) => record.id" bordered
:loading="tableLoading" :scroll="{x:1200}"
:data-source="dataSource"/>
表头数据
const rightColumns = ref([
{
title: '项目阶段', dataIndex: 'projectPhaseName', fixed: true, width: 150,
align: 'center',
customCell: (record, index) => {
return {
rowSpan: getRowSpan(record.projectPhaseName, dataSource.value, 'projectPhaseName', index,record)
}
}
},
{
title: '任务类别',
dataIndex: 'taskTypeName',
fixed: true,
width: 130,
align: 'center',
},
{title: '名称', dataIndex: 'name', width: 260, align: 'center'},
{
title: '负责人',
dataIndex: 'principalsName',
width: 220,
align: 'center'
},
{
title: '状态',
dataIndex: 'statusName',
width: 100,
align: 'center',
customRender: ({ text }) => {
return (
<div>
{text==='已暂停' ? <span style="color:red">{text}</span> : text}
</div>
)
}
},
{
title: '是否超期',
dataIndex: 'isDelayName',
width: 100,
align: 'center',
customRender: ({ text }) => {
return (
<div>
{text==='是' ? <span style="color:red">{text}</span> : text}
</div>
)
}
}, {
title: '进度',
dataIndex: 'progressName',
width: 90,
align: 'center'
},
{title: '开始日期', dataIndex: 'startTime', width: 120, align: 'center'},
{title: '实际开始日期', dataIndex: 'actualStartTime', width: 120, align: 'center'},
{title: '结束日期', dataIndex: 'endTime', width: 120, align: 'center'},
{title: '实际结束日期', dataIndex: 'actualEndTime', width: 120, align: 'center'},
{
title: '计划天数',
dataIndex: 'planDays',
width: 130, align: 'center'
},
{
title: '实际天数',
dataIndex: 'actualDays',
align: 'center',
width: 130
},
])
合并方法
function getRowSpan(text, data, key, index, record) {
if (record.taskTypeName === '子任务') {
return 0
}
let rowSpan = 1
// 上一行该列数据是否一样
if (index !== 0 && data && text === data[index - 1][key]) {
return 0
}
// 判断下一行是否相等,同时不是子集
for (let i = index + 1; i < data.length; i++) {
if (text !== data[i][key]) {
break
} else if (data[i].children?.length > 0) {
rowSpan += data[i].children?.length + 1
} else {
rowSpan++
}
}
// 任务单独一个阶段时
if (data[index].children?.length > 0) {
rowSpan = data[index].children?.length + 1
}
return rowSpan
}
最终实现效果
注:expandIconColumnIndex用以展开到第二列,该属性并未出现在官方文档,是问了一个前端大佬在table源码里面找到的;只有当任务类别为‘任务’时存在子集,需要展开。