el-table:列表中相同名称的数据实现行合并

1. 效果图

效果图

2. 页面

使用el-table的span-method属性控制合并行, 和row-class-name属性控制行样式


...省略...

3. 方法

handleData: 处理表格数据,将同一名称的数据进行组合
getSpanArr:获取单元格的合并行数
objectSpanMethod:合并单元格
getRowClass:设置表格行的样式类

/**
 * 处理表格数据,将同一名称的数据进行组合
 */
const handleData = () => {
  // 排序方法1:将相同名称的数据移动在一起,但会导致所有数据的顺序都被改变
  // state.tableData.sort((a, b) => {
  //   if (a.name != b.name) {
  //     return a.name.localeCompare(b.name) // stringObject.localeCompare(target): 用本地特定的顺序来比较两个字符串
  //   }
  // })

  // 排序方法2:只移动有相同名称的数据,保持其它数据的相对顺序不改变
  let keys = [] // 唯一值的数组
  state.tableData.forEach((item, index) => {
    if (!keys.includes(item.moduleName)) {
      keys.push(item.moduleName)
    }
  })

  let temp = []
  keys.forEach((item) => {  // 将同一名称的数据放在相邻位置
    state.tableData.forEach((cell) => {
      if (item === cell.name) {
        temp.push(cell)
      }
    })
  })

  state.tableData = temp
  getSpanArr(state.tableData)
}

let spanArr = [] // 每一条数据合并的行数,避免表格错乱!
/**
 *  获取单元格的合并行数
 * */
const getSpanArr = (data) => {
  let position  // 当前合并的行位置(连续相同名称的第一条数据位置)
  spanArr = []
  data.forEach((item, index) => {
    if (index === 0) {  // 第一行, 不进行处理
      spanArr.push(1)
      position = 0
    } else {
      if (data[index].name === data[index - 1].name) {
        // 当条数据跟上一条数据名称相同,要合并
        spanArr[position] += 1  // 首条相同名称行合并行数增加
        spanArr.push(0) // 当前行消除
      } else { // 不需要处理的数据
        spanArr.push(1)
        position = index
      }
    }
  })
}

/** 
 * 合并单元格,此处只合并前三列的属性值 
 * 
*/
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
  if (columnIndex < 3) {  // 对前三列进行操作
    const _row = spanArr[rowIndex]  // 合并行数
    const _col = _row > 0 ? 1 : 0 // 合并列数,1:不改变,0:被消除
    return {
      rowspan: _row,
      colspan: _col
    }
  }
}

/**
 * 设置表格行的样式类(去除合并行内多余的线条)
 */
const getRowClass = ({ row, rowIndex }) => {
  if (spanArr[rowIndex] > 1) { // 相同名称排列的首行数据
    return 'show-span-row'
  } else if (spanArr[rowIndex] === 0 && spanArr[rowIndex + 1] === 0) {  // 相同名称不处于末尾的被合并数据
    return 'center-span'
  }
}

4. 样式

getRowClass设置的css样式

.el-table {
  :deep(tr) {
    &.show-span-row {
      td:nth-of-type(n + 3) {
        border-bottom: none;
      }
    }

    &.center-span {
      td {
        border-bottom: none;
      }
    }
  }
}

5. 整体代码(Vue3)






5. 其它

objectSpanMethod原理:对每一个单元格返回一个[rowSpan, colSpan]数组, rowSpan表示当前单元格会展示的行数,colSpan表示当前单元格会展示的列数,设置为0时当前单元格被消除。

参考文章:
element-ui table :span-method(行合并)
js将数组中的相同项放在毗邻位置

你可能感兴趣的:(el-table:列表中相同名称的数据实现行合并)