背景
在最近的一个迭代上,有一个功能点是在表格中做一个合并单元格的效果。大致如下图
只有第一列合并行,跨行。合并的规则是纵向相邻的连续N行,如果id一致,则合并。
看到这个需求一开始我以为很简单,表格跨行.跨列,不就是设置rowspan
和colspan
。于是我就把这个功能点放到最后来实现了。
等到真正去做的时候,查了一下element的文档,发现并没那么简单。需要自己动手去写一个方法设置每个单元格的rowspan和 colspan。 眼看要提测了,想偷懒的想借他山之石。于是在前端群里问了一下,又没人写过类似的,解决一下。后来想想真是多此一举,关键时刻一定要相信自己。何况很久没有遇到有意思的题目了。看起来很有趣。在前端群里得到否定答案的我,决定加班好好研究一下这个合并的规则。为他人铺一个康庄大道。
认真研究
以下是官方提供的一个在第一列合并行的例子
代码语言:javascript复制objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1,
}
} else {
return {
rowspan: 0,
colspan: 0,
}
}
}
}
在el-table
标签上设置 :span-method="objectSpanMethod"
就能实现在第一列的偶数行被合并。这个例子写的很简单。没有掺杂任何业务逻辑。该方法返回的数据可以是 一个包含rowspan和colspan的对象。 {rowspan: 2, colspan: 1}
表示当前单元格占用二行一列。 {rowspan: 0, colspan: 0}
表示当前单元格缺少,或被合并了。
row表示当前行。column表示当前列,rowIndex当前行的索引,columnIndex 当前列的索引。
在日常开发中,常见的合并行,或合并列的场景是根据后端返回的一个数组,依据其中的某一个属性来合并行。比如有一个表格,统计每个人车辆的所属情况。后端是以车辆为粒度返回数据。当一个人有多台车时,(比如我)就需要将姓名那一列合并行。这样做后,信息的层次和结构会更加清晰。表现得更加具体,形象。
思路实现
根据合并的规则可以知道,在我的需求中,只需要确定rowspan的值即可。也就是合并多少行,对于被合并的单元格,rowspan和colspan都为零。而合并的单元格,他的colspan为1,因为它不跨列。
于是拿到表格数据后,对表格数据进行以下处理。假设要合并的字段为runPeriod
。相同的runPeriod单元格合并起来。
addSpanRows(tableData) {
let pos = 0
let len = tableData.length
for (let i = 0; i < len; i ) {
const item = tableData[i]
if (i === 0) {
item.$rows = 1
pos = 0
}
if (i !== 0) {
if (item.runPeriod === tableData[i - 1].runPeriod) {
item.$rows = 0
tableData[pos].$rows = tableData[pos].$rows 1
} else {
item.$rows = 1
pos = i
}
}
}
}
使用pos记录出现重复的元素的索引,找到一个重复后就将索引为pos的记录的 $rows 加1,找不到就将pos设置为当前遍历的索引
在
代码语言:javascript复制spanMethod({row, _, __, columnIndex}) {
if (columnIndex === 0) {
return {
rowspan: row.$rows,
colspan: row.$rows ? 1 : 0,
}
}
}
当时第一列时使用$rows进行合并单元格。
这样配置一下即可。