Element-plush 合并单元格

需求:将查询出来的表格数据按照值相同的原则进行合并,行和列都要合并。
效果:
在这里插入图片描述

技术分析:

1、表格插件使用 Element-plush 提供的组件 el-table 实现。
2、 el-table 本身就提供了一个 span-method tabel 属性供用户实现单元格合并的扩展。
3、span-method 接收一个函数,这个函数需用户自己实现,并需要返回一个二维数组或者对象。
4、el-table 在渲染每一个单元格的时候,都会调用这个函数获取对当前单元格合并情况,并根据获取到的合并情况进行渲染,并且调用的规律是一行一行的调用,例如:在渲染第一行的时候会将这一行上的所有的列处理完成之后才会处理第二行,第二行的处理逻辑也是相似的。

思路分析:

1、在获取到数据的之后,首先根据数据情况判断单元格合并情况,即:生成需要合并行的二维数组情况,生成需要合并列的二维数组情况。
2、在 span-method 调用的函数中,每次根据函数返回来的 rowIndex 和 columnIndex 就可以确定对应的单元格的合并情况。

技术实现:

1、数据获取到之后,调用 handleSpanData 函数生成单元格合并情况,span-method 接收 spanObjectMethod 函数渲染单元格。
① needSpanColumn:存储每一列对应的每一个单元格的合并情况。例如:{0: [1, 2, 0]} 表明第一行数据的第一列不需要合并;第一行数据的第二列需要合并,并向后合并两列;第一行数据的第三列不需要合并,并且隐藏显示。
② needSpanRow:存储每一列对应的每一个单元格的合并情况。例如:{0: [2]} 、{1: [0]} 表明第一列数据的第一行对应的单元格需要合并,并向后下合并两行,并且第一列数据的第二行对应的单元格隐藏显示。

const handleSpanData = () => {  
  const dataDetails = tableData || [];  
  const needSpanColumn = {};  
  const columns = tableOption.map((item) => item.prop);  
  // 行  列 -> 横向比较,合并的是列,代表是当前行需要合并的单元格数量  
  dataDetails.forEach((row, rowIndex) => {  
    let rowFlag = -1;  
    needSpanColumn[rowIndex] = [1];  
    columns.forEach((column, columnIndex) => {  
      if (columnIndex === 0) {  
        return;  
      }  
  
      if (rowFlag === -1) {  
        rowFlag = columnIndex - 1;  
      }  
  
      if (row[column] === row[columns[columnIndex - 1]]) {  
        needSpanColumn[rowIndex][rowFlag] += 1;  
        needSpanColumn[rowIndex].push(0);  
        return;  
      }  
      needSpanColumn[rowIndex].push(1);  
      rowFlag = -1;  
    });  
  });  
  console.table(needSpanColumn);  
  
  // 列  行 -> 竖向比较, 代表是当前列需要合并的单行数  
  const needSpanRow = {};  
  columns.forEach((column, columnIndex) => {  
    let columnFlag = -1;  
    needSpanRow[columnIndex] = [1];  
    dataDetails.forEach((row, rowIndex) => {  
      if (rowIndex === 0) {  
        return;  
      }  
  
      if (columnFlag === -1) {  
        columnFlag = rowIndex - 1;  
      }  
  
      if (row[column] === dataDetails[rowIndex - 1][column]) {  
        needSpanRow[columnIndex][columnFlag] += 1;  
        needSpanRow[columnIndex].push(0);  
        return;  
      }  
  
      needSpanRow[columnIndex].push(1);  
      columnFlag = -1;  
    });  
  });  
  
  console.table(needSpanRow);  
  return { needSpanColumn, needSpanRow };  
};

const spanObjectMethod = ({ row, column, rowIndex, columnIndex }) => {  
  console.info('🚀 ~ file:TableSpan.vue method:spanObjectMethod line:73 -----', rowIndex, columnIndex);  
  return [needSpanRow1[columnIndex][rowIndex], needSpanColumn1[rowIndex][columnIndex]];  
};

测试数据验证:

const tableData: any[] = [
    {"item1": "1","item2": "3","item3": "3","item4": "3","item5": "4"},
    {"item1": "2","item2": "5","item3": "5","item4": "5","item5": "4"},
    {"item1": "3","item2": "3","item3": "2","item4": "4","item5": "5"},
    {"item1": "4","item2": "9","item3": "7","item4": "4","item5": "5"},
    {"item1": "5","item2": "6","item3": "7","item4": "8","item5": "9"}
];

测试效果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜间沐水人

文章编写不易,一分钱也是爱。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值