eltable错误合并单元格后的检查思路

相信很多人都有被elementui的合并表格搞疯过,合并了这一列的表格,别的单元格又出问题,这次记录一下我排查错误的过程。

首先,需要的效果是这样的

如果没写过合并表格的同学,可以先去翻阅一下elementui官网看看是通过什么方法合并的(span-method),也看看数据的结构应该怎么设计,有基础的同学可以直接看疑问2或者总结。

拿到这个需求,很明显我们要去写一个table

js 复制代码
<el-table
  :data="templateTableData"
  style="width: 100%"
  border
  :span-method="objectSpanMethod"
  @selection-change="handleSelectionChange"
>
  <el-table-column type="selection" width="40"> </el-table-column>
  <el-table-column prop="summaryName" label="摘要" width="400">
  </el-table-column>
  <el-table-column prop="voucherSubjectName" label="科目">
  </el-table-column>
  <el-table-column prop="voucherWordName" label="方向" width="180">
  </el-table-column>
  <el-table-column prop="loanAmount" label="金额" width="180">
  </el-table-column>
  <el-table-column
    fixed="right"
    label="操作"
    width="150"
    align="center"
  >
    <template slot-scope="scope">
      <el-button type="text" @click="modifyHandler(scope.row)"
        >修改</el-button
      >
      <el-button type="text" @click="deleteHandler(scope.row)"
        >删除</el-button
      >
    </template>
  </el-table-column>
</el-table>

疑问1:我怎么知道一条数据占几行,先来看后端返回的数据

后端是一条一条返回的,但是需要合并的数据,会有个id是一样的,比如我这里,第一条数据占3行,第二条数据占4行,第三条数据占5行,那么第一条数据都有一个id是一样并且是唯一的,第二第三行也一样,比如我这里的结构是这样的

js 复制代码
const tableData = [
    { voucherId: '1', summaryName: '合计1', },
    { voucherId: '1', summaryName: '名字1-1', voucherSubjectName: '科目1', voucherWordName: '记', loanAmount: 1 },
    { voucherId: '1', summaryName: '名字1-2', voucherSubjectName: '科目2', voucherWordName: '记', loanAmount: 2 },
    { voucherId: '2', summaryName: '合计2', voucherSubjectName: '科目3', voucherWordName: '记', loanAmount: 3 },
    { voucherId: '2', summaryName: '名字2-1', voucherSubjectName: '科目4', voucherWordName: '记', loanAmount: 4 },
    { voucherId: '2', summaryName: '名字2-2', voucherSubjectName: '科目5', voucherWordName: '记', loanAmount: 5 },
    { voucherId: '2', summaryName: '名字2-3', voucherSubjectName: '科目6', voucherWordName: '记', loanAmount: 6 },
    { voucherId: '3', summaryName: '合计3', voucherSubjectName: '科目7', voucherWordName: '记', loanAmount: 7 },
    { voucherId: '3', summaryName: '名字3-1', voucherSubjectName: '科目8', voucherWordName: '记', loanAmount: 8 },
    { voucherId: '3', summaryName: '名字3-2', voucherSubjectName: '科目9', voucherWordName: '记', loanAmount: 9 },
    { voucherId: '3', summaryName: '名字3-3', voucherSubjectName: '科目10', voucherWordName: '记', loanAmount: 10 },
    { voucherId: '3', summaryName: '名字3-4', voucherSubjectName: '科目11', voucherWordName: '记', loanAmount: 11 },
]

这里需要写一个方法,去获取需要合并的行,复制可直接使用

js 复制代码
computed: {
    mergingCols() {
      const mergingCols = [];
      let mergingPos = 0;
      for (let i = 0; i < this.tableData.length; i++) {
        if (i === 0) {
          mergingCols.push(1);
          mergingPos = 0;
        } else {
          if (
            this.tableData[i].voucherId === this.tableData[i - 1].voucherId
          ) {
            mergingCols[mergingPos] += 1;
            mergingCols.push(0);
          } else {
            mergingCols.push(1);
            mergingPos = i;
          }
        }
      }
      return mergingCols;
    },
  },

mergingCols返回的数据就是这样的:

意思就是第0个index需要合并3条数据,第3个index开始就是第二条数据,需要合并4条数据,第8个index表示第三行,需要合并5条数据,这里的0就是表示被合并的行。

疑问2:我当时错误合并方式是什么?

按照需求,需要的是第一列的selection合并,然后每条数据的第一行摘要占满科目、方向和余额这几列,最后操作列再合并。

那我去循环mergingCols的时候,当columnIndex为0和5的时候去合并mergingCols不为0的行数(合并selection和操作列),当遇到columnIndex为1的时候,合并3列,即1-4列,不就完了,说干就干。

js 复制代码
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex == 0 || columnIndex == 5) {
        if (this.mergingCols[rowIndex] > 0) {
          return [this.mergingCols[rowIndex], 1];
        } else {
        //遇到0就不管啦
          return [0, 0];
        }
      } else if (columnIndex == 1) {
        if (this.mergingCols[rowIndex] > 0) {
          return [1, 4];
        }
      }
    },

写出来之后就烦恼了,操作列空了。然后自顾自调了好久都没调出来,后来打开控制台查看元素。

重点来了

来看第一条数据,好几个单元格跑外面去了,很明显是被撑出去的,但是操作列的第一行单元格还在,第二行第三行的数据没有和第一行合并在一起,反而被挤出去了,而且合并的应该是index为0-2的列,但是实际是1-3,这种情况大概率是某些单元格没有意义,应该被清除的,但是没清除还留在表格里,所以就被撑出去了。

然后我对着元素审查手动删除了几个单元格,正常了!!!

是什么情况???我们删除的元素是el-table_1_column_3、el-table_1_column_4、el-table_1_column_5,也就是说当columnIndex为2、3、4(el-table_1_column是从1开始的)的时候我没有return [0,0]清除掉一些因为第一行合并了三列单元格而撑出去的原来的元素,很明显我要再添加一个else,然后清除多余的元素。

js 复制代码
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      console.log('columnIndex',columnIndex)
      if (columnIndex == 0 || columnIndex == 5) {
        if (this.mergingCols[rowIndex] > 0) {
          return [this.mergingCols[rowIndex], 1];
        } else {
          return [0, 0];
        }
      } else if (columnIndex == 1) {
        if (this.mergingCols[rowIndex] > 0) {
          return [1, 4];
        }
      } 
      //加上else
      else {
          return [0, 0];
      }
    },

事与愿违,这些操作列好了,但是2、3、4列全出问题了,应该是有些单元格是需要保持原样的,但是被我给无情清除掉了。因为class后的index极度不连贯。

结合上面,我应该是要在2、3、4列的时候,并且只清掉第一行因为摘要合并了科目、方向、余额 多出的单元格,只需要在上面的else再添加一个条件。

js 复制代码
 else {
     //每条数据的第一行
    if (this.mergingCols[rowIndex] > 0) {
      return [0, 0];
    }
  }

最后总结

当我们在做合并表格的时候,如果有些单元格变成了空白,应该打开F12,查看元素,大概率是前面有合并单元,合并后,多出来一些无意义的单元格给顶出去了,要尝试手动delete一些元素,然后分析这些元素的class对应的column的index,这些tr里面的td会超出我们预期的数量。像下面这样,第一行合并完之后应该只有3个单元格,但是出现了6个

当检查到class不连贯,跳跃很大,并且td少于预期的数量,很明显是被自己误清除了一些有意义的单元格,这时要看代码里面return [0,0]的条件是否符合逻辑,像这个。

以上是我自己在做合并单元格时的一些检查思路,希望对大家有用。

相关推荐
LuciferHuang3 小时前
震惊!三万star开源项目竟有致命Bug?
前端·javascript·debug
GISer_Jing3 小时前
前端实习总结——案例与大纲
前端·javascript
天天进步20153 小时前
前端工程化:Webpack从入门到精通
前端·webpack·node.js
姑苏洛言4 小时前
编写产品需求文档:黄历日历小程序
前端·javascript·后端
知识分享小能手5 小时前
Vue3 学习教程,从入门到精通,使用 VSCode 开发 Vue3 的详细指南(3)
前端·javascript·vue.js·学习·前端框架·vue·vue3
姑苏洛言5 小时前
搭建一款结合传统黄历功能的日历小程序
前端·javascript·后端
你的人类朋友6 小时前
🤔什么时候用BFF架构?
前端·javascript·后端
知识分享小能手6 小时前
Bootstrap 5学习教程,从入门到精通,Bootstrap 5 表单验证语法知识点及案例代码(34)
前端·javascript·学习·typescript·bootstrap·html·css3
一只小灿灿7 小时前
前端计算机视觉:使用 OpenCV.js 在浏览器中实现图像处理
前端·opencv·计算机视觉