更新一个新写法(场景不一样了)
// 遍历数据生成合并规则数组(spanArr),记录相同 projectId 的连续行数
methods: {
getSpanArr(data) {
const spanArr = [];
let position = 0; // 记录相同ID的起始位置
data.forEach((item, index) => {
if (index === 0) {
spanArr.push(1);
} else {
// 当前行projectId与前一行相同则合并
if (item.projectId === data[index - 1].projectId) {
spanArr[position] += 1;
spanArr.push(0); // 标记被合并的行
} else {
spanArr.push(1);
position = index; // 更新起始位置
}
}
});
this.spanArr = spanArr;
}
}
//通过 objectSpanMethod 方法应用合并规则
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) { // 仅合并第一列
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return { rowspan: _row, colspan: _col };
}
}
}
<el-table
:data="tableData"
:span-method="objectSpanMethod"
row-key="id">
<el-table-column prop="projectId" label="项目ID" />
<!-- 其他列 -->
</el-table>
- 数据排序
需确保相同 projectId 的数据连续排列,可通过Array.sort()
预处理. - 动态更新
数据变化时需重新调用getSpanArr()
方法. - 性能优化
大数据量时建议后端返回已分组数据减少前端计算.
参考文章:https://www.cnblogs.com/gggggggxin/p/14311726.html
在mounted方法中调用 onMergeLines()
const onMergeLines = () => {
// 先给所有的数据都加一个v.rowspan = 1
tableData.value.forEach((item) => {
item.rowspan = 1
})
// 双层循环
for (let i = 0; i < tableData.value.length; i++) {
// 内层循环,上面已经给所有的行都加了item.rowspan = 1
// 这里进行判断
// 如果当前行的cid和下一行的cid相等
// 就把当前item.rowspan + 1
// 下一行的item.rowspan - 1
for (let j = i + 1; j < tableData.value.length; j++) {
//此处可根据相同字段进行合并,此处是根据的id
if (tableData.value[i].id === tableData.value[j].id) {
tableData.value[i].rowspan++
tableData.value[j].rowspan--
}
}
// 这里跳过已经重复的数据
i = i + tableData.value[i].rowspan - 1
}
}
//合并单元格
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
//第一列
if (columnIndex === 0) {
return {
rowspan: row.rowspan,
colspan: 1
}
}
//第二列
if (columnIndex === 1) {
return {
rowspan: row.rowspan,
colspan: 1
}
}
//第三列
if (columnIndex === 2) {
return {
rowspan: row.rowspan,
colspan: 1
}
}
//第四列
if (columnIndex === 3) {
return {
rowspan: row.rowspan,
colspan: 1
}
}
//最后一列
if (columnIndex === 18) {
return {
rowspan: row.rowspan,
colspan: 1
}
}
}