Element UI el-table自动合并行列

1,922 阅读2分钟

背景:项目中需要针对相等的行和列自行合并,上下相等的单元格进行行合并,左右相等的单元格进行列合并。效果如下图所示

image.png

span-method介绍

el-table想实现合并行列,就绕不开span-method,官方文档介绍如下

通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspancolspan的对象。

Function({ row, column, rowIndex, columnIndex })

简单来说,span-method会遍历每一个单元格,

  • 返回 [0, 0], 不渲染此单元格,被合并
  • 返回 [n, 1],行合并效果,占n行

image.png

  • 返回 [1, n],列合并效果,占n列

image.png

  • 返回 [1, 1],正常渲染单元格,无合并效果

理解了span-method原理,下面来看核心思路

自动合并实现思路

通过span-method方法,每个单元格都返回自己的rowspan和colspan

查找前一行,判断当前与前一行是否相等,相等则返回[0,0],则不显示,被合并

默认rowspan为1(n=1),查找之后还有多少行和当前行相等,返回[n, 1],则实现合并行

所有上下相邻值相等的行都合并完成;

列合并思路同上

查找前一列prop,判断当前列值是否与前一列prop值相等,相等则返回[0,0],则不显示,被合并

默认colspan为1(n=1),查找之后有多少列和当前列的值相同,返回[1, n],进行合并

所有左右相邻值相等的列都合并完成;

span-method代码如下

const objectSpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex,
}: SpanMethodProps) => {
  // 此例针对前三列进行操作
  if (columnIndex >= 0 && columnIndex <= 2) {
    // 行合并逻辑
    // 查找前一行
    const previousRow = rowIndex > 0 ? tableData.value[rowIndex - 1] : null

    // 判断当前行和前一行的值是否相同
    if (previousRow && previousRow[column.property] === row[column.property]) {
      return [0, 0] // 如果相同,返回 [0, 0] 表示不显示此单元格
    }

    // 查找之后有多少行和当前行的值相同,进行合并
    let rowspan = 1
    for (let i = rowIndex + 1; i < tableData.value.length; i++) {
      if (tableData.value[i][column.property] === row[column.property]) {
        rowspan++
      } else {
        break
      }
    }

    // 列合并逻辑
    // 查找前一列prop - 针对日期列前列
    const previousProp =
      columnIndex > 0 ? columns.value[columnIndex - 1].prop : null

    // 判断当前列与前一列的值是否相同
    if (previousProp && row[previousProp] === row[column.property]) {
      return [0, 0]
    }

    // 查找之后有多少列和当前列的值相同,进行合并
    let colspan = 1
    for (let i = columnIndex + 1; i <= 2; i++) {
      if (row[columns.value[i].prop] === row[column.property]) {
        colspan++
      } else {
        break
      }
    }

    return [rowspan, colspan] // 合并的行数 rowspan 不需合并列的返回
  }
}