Ant Design Vue a-table实现自动合并行列

Element UI el-table自动合并行列

背景可看上面这篇文章,由于项目技术选型,原本用Element UI写的demo,后续选用Ant Design Vue UI库,核心思路不变,不过a-table支持的实现方法略有不同

可实现的效果

针对固定列(下图是前三列)可做到针对相等的行和列自行合并,上下相等的单元格进行行合并,左右相等的单元格进行列合并。

a-table表格行列合并实现

先来了解下a-table如何支持表格行列合并,官方文档描述如下:

  • 表头只支持列合并,使用 column 里的 colSpan 进行设置。
  • 表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。

第二点跟el-table的思路一致,即针对每一个单元格返回{rowSpan, colSpan}来决定如何渲染,我们下面也将针对第二点进行我们的核心实现思路

customCell

Function(record, rowIndex, column) 相比el-table的span-method 缺少columnIndex参数

与el-table的span-method方法针对每一个单元格进行执行不同,customCell是Columns的API,针对你需要操作的列执行合并逻辑

在span-method中我们通过if (columnIndex >= 0 && columnIndex <= 2)进行合并范围划分,而a-table则是只有前三列列配置中增加{ dataIndex: 'example', title: '需进行合并的列', customCell: cellMerge }

自动合并实现思路

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

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

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

列合并思路同上

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

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

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

代码实现

在上面提到customCell缺少columnIndex参数,但是我们实现列合并时需要此参数,所以增加一个getColumnIndex方法

ts 复制代码
// 获取当前列的索引
const getColumnIndex = (dataIndex: string) => {
  return columns.value.findIndex(col => col.dataIndex === dataIndex);
};

const cellMerge =  (record: any, rowIndex: number, column: Record<string, any>)=> {
  // 获取columnIndex
  const columnIndex = getColumnIndex(column.dataIndex);
  
  // 行合并逻辑
  // 查找前一行
  const previousRow = rowIndex > 0 ? tableData.value[rowIndex - 1] : null

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

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

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

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

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

  return {rowSpan, colSpan} // 合并的行数 rowspan 不需合并列的返回
}

将cellMerge方法加入到需要进行合并的列配置中,下例是前三列需要自动行列合并

ts 复制代码
const mockCols = [
  { dataIndex: 'col1', title: '列名1', customCell: cellMerge },
  { dataIndex: 'col2', title: '列名2', customCell: cellMerge },
  { dataIndex: 'col3', title: '列名3', customCell: cellMerge },
  { dataIndex: 'col4', title: '列名4' },
  { dataIndex: 'col5', title: '列名5' },
  { dataIndex: 'col6', title: '列名6' },
]
相关推荐
然我几秒前
不用 Redux 也能全局状态管理?看我用 useReducer+Context 搞个 Todo 应用
前端·javascript·react.js
前端小巷子5 分钟前
Web 实时通信:从短轮询到 WebSocket
前端·javascript·面试
神仙别闹9 分钟前
基于C#+SQL Server实现(Web)学生选课管理系统
前端·数据库·c#
web前端神器15 分钟前
指定阿里镜像原理
前端
枷锁—sha20 分钟前
【DVWA系列】——CSRF——Medium详细教程
android·服务器·前端·web安全·网络安全·csrf
枷锁—sha21 分钟前
跨站请求伪造漏洞(CSRF)详解
运维·服务器·前端·web安全·网络安全·csrf
群联云防护小杜37 分钟前
深度隐匿源IP:高防+群联AI云防护防绕过实战
运维·服务器·前端·网络·人工智能·网络协议·tcp/ip
汉得数字平台1 小时前
【鲲苍提效】全面洞察用户体验,助力打造高性能前端应用
前端·前端监控
花海如潮淹1 小时前
前端性能追踪工具:用户体验的毫秒战争
前端·笔记·ux
_丿丨丨_6 小时前
XSS(跨站脚本攻击)
前端·网络·xss