在实际项目中,使用 Element UI 的 el-table 时,经常会遇到需要按条件合并单元格的需求。
本文将带你实现一个常见但稍复杂的场景:
第二列的合并条件:必须同时满足「第一列相同 + 第二列相同」才合并
如果第二列不同,即使第一列相同,也不合并
一、需求:
假设我们有如下表格数据:
tableData: [
{ col1: 'A', col2: 'X', col3: 1 },
{ col1: 'A', col2: 'X', col3: 2 },
{ col1: 'A', col2: 'Y', col3: 3 },
{ col1: 'A', col2: 'Y', col3: 4 },
{ col1: 'B', col2: 'X', col3: 5 },
{ col1: 'B', col2: 'Z', col3: 6 }
]
目标效果:
| 第一列 | 第二列 | 第三列 |
|---|---|---|
| A | X | 1 |
| 2 | ||
| Y | 3 | |
| 4 | ||
| B | X | 5 |
| Z | 6 |
二、实现原理:
Element UI 提供了一个关键属性:
<span-method="spanMethod">
通过这个方法,我们可以控制每个单元格的:
-
合并行数(rowspan)
-
合并列数(colspan)
返回值格式:
[rowspan, colspan]
三、核心实现代码
span-method 方法
javascript
methods: {
spanMethod({ row, column, rowIndex, columnIndex }) {
const data = this.tableData
// 第一列:按 col1 合并
if (columnIndex === 0) {
const current = row.col1
let rowspan = 1
for (let i = rowIndex + 1; i < data.length; i++) {
if (data[i].col1 === current) {
rowspan++
} else {
break
}
}
// 如果是重复项,隐藏
if (rowIndex > 0 && data[rowIndex - 1].col1 === current) {
return [0, 0]
}
return [rowspan, 1]
}
// 第二列:按 col1 + col2 同时相同才合并(重点)
if (columnIndex === 1) {
const currentCol1 = row.col1
const currentCol2 = row.col2
let rowspan = 1
for (let i = rowIndex + 1; i < data.length; i++) {
if (
data[i].col1 === currentCol1 &&
data[i].col2 === currentCol2
) {
rowspan++
} else {
break
}
}
// 如果上一行满足相同条件,则隐藏
if (
rowIndex > 0 &&
data[rowIndex - 1].col1 === currentCol1 &&
data[rowIndex - 1].col2 === currentCol2
) {
return [0, 0]
}
return [rowspan, 1]
}
}
}
表格使用方式
html
<el-table
:data="tableData"
:span-method="spanMethod"
border
>
<el-table-column prop="col1" label="第一列"></el-table-column>
<el-table-column prop="col2" label="第二列"></el-table-column>
<el-table-column prop="col3" label="第三列"></el-table-column>
</el-table>
四、关键注意事项(非常重要)
1. 数据必须排序
合并单元格的前提是:相同数据必须是连续的
错误示例(会导致合并错乱):
javascript
[
{ col1: 'A', col2: 'X' },
{ col1: 'A', col2: 'Y' },
{ col1: 'A', col2: 'X' } // ❌ 被打断
]
正确做法:
javascript
// 先按 col1,再按 col2 排序
data.sort((a, b) => {
if (a.col1 === b.col1) {
return a.col2.localeCompare(b.col2)
}
return a.col1.localeCompare(b.col1)
})
总结
本质一句话:
👉 Element UI 合并单元格 = 控制"什么时候返回 [0,0] + 什么时候计算 rowspan"
而本例的核心点在于:
✔ 第二列不仅看自己
✔ 还要依赖第一列
✔ 实现"分组中的子分组合并"