el-table 合并单元格(合并行)

该代码示例展示了在Vue.js项目中,利用Element-UI的table组件和objectSpanMethod方法来实现表格中特定列(如gzID和gzTroubles)的单元格合并。当同一列的连续行数据相同时,会进行行合并,以减少重复信息的显示。

1.  添加 :span-method="objectSpanMethod"

 2.  写objectSpanMethod 方法

//#region  合并单元格
    // 这个方法是 element-ui提供的单元格合并方法
    // objectSpanMethod 传入了 { row, column, rowIndex, columnIndex }
    // row: 当前行
    // column: 当前列
    // rowIndex:当前行号
    // columnIndex :当前列号
    // 1代表:独占一行
    // 更大的自然数:代表合并了若干行
    // 0:代表“消失”的哪那一个单元格,后面的单元格向前推一格
    mergeCol(id, rowIndex) {
      debugger;
      // 合并单元格
      // id:属性名
      // rowIndex:行索引值
      var idName = this.TableData[rowIndex][id]; // 获取当前单元格的值
      if (rowIndex > 0) {
        // 判断是不是第一行
        // eslint-disable-next-line eqeqeq
        if (this.TableData[rowIndex][id] != this.TableData[rowIndex - 1][id]) {
          // 先判断当前单元格的值是不是和上一行的值相等
          var i = rowIndex;
          var num = 0; // 定义一个变量i,用于记录行索引值并进行循环,num用于计数
          while (i < this.TableData.length) {
            // 当索引值小于table的数组长度时,循环执行
            if (this.TableData[i][id] === idName) {
              // 判断循环的单元格的值是不是和当前行的值相等
              i++; // 如果相等,则索引值加1
              num++; // 合并的num计数加1
            } else {
              i = this.TableData.length; // 如果不相等,将索引值设置为table的数组长度,跳出循环
            }
          }
          return {
            rowspan: num, // 最终将合并的行数返回
            colspan: 1,
          };
        } else {
          return {
            rowspan: 0, // 如果相等,则将rowspan设置为0
            colspan: 1,
          };
        }
      } else {
        // 如果是第一行,则直接返回
        let i = rowIndex;
        let num = 0;
        while (i < this.TableData.length) {
          // 当索引值小于table的数组长度时,循环执行
          if (this.TableData[i][id] === idName) {
            i++;
            num++;
          } else {
            i = this.TableData.length;
          }
        }
        return {
          rowspan: num,
          colspan: 1,
        };
      }
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 合并单元格
      switch (
        columnIndex // 将列索引作为判断值
      ) {
        // 通过传递不同的列索引和需要合并的属性名,可以实现不同列的合并(索引0,1 指的是页面上的0,1)
        // gzTroubles,gzID 这两个字段是我要合并的字段名,
        case 1:
          return this.mergeCol("gzTroubles", rowIndex);
        case 0:
          return this.mergeCol("gzID", rowIndex);
      }
    },
    //#endregion

其中,switch中 0和1 是根据下面这张图中的顺序来的,

 完整代码如下:

<template>
  <div class="pCindex">
    <el-table
      ref="tableRef"
      :data="TableData"
      class="tableStyle"
      :span-method="objectSpanMethod"
      border
    >
      <el-table-column
        align="center"
        prop="gzID"
        :label="lable.gzID"
        width="80"
      >
      </el-table-column>
      <el-table-column
        align="center"
        prop="gzTroubles"
        :label="lable.gzTroubles"
      >
      </el-table-column>
      <el-table-column
        header-align="center"
        prop="gzReason"
        :label="lable.gzReason"
      ></el-table-column>
      <el-table-column
        header-align="center"
        prop="gzWay"
        :label="lable.gzWay"
      ></el-table-column>
    </el-table>
   
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
     
    
      
      lable: {
        gzID: "序号",
        gzTroubles: "故障现象",
        gzReason: "故障原因",
        gzWay: "排除方法",
      },

      TableData: [
        {
          gzID: "1",
          gzTroubles: "发动机胜多负少的温度过高",
          gzReason: "1.是的",
          gzWay: "1.打开上翻门",
        },
        {
          gzID: "1",
          gzTroubles: "发动机胜多负少的温度过高",
          gzReason: "2.散热风机有噪音",
          gzWay: "2.转轴上加润滑油",
        },
        {
          gzID: "2",
          gzTroubles: "发动机不能起动",
          gzReason: "1.电瓶电压不足,接线柱松动或氧化",
          gzWay: "1.充电、打磨接头并接牢",
        },
        {
          gzID: "3",
          gzTroubles: "发动机不等等能起动",
          gzReason: "2.燃油不足是否",
          gzWay: "2.加油或排气",
        },
        
      ],
    };
  },
  watch: {},
  mounted() {},
  methods: {
    //#region  合并单元格
    // 这个方法是 element-ui提供的单元格合并方法
    // objectSpanMethod 传入了 { row, column, rowIndex, columnIndex }
    // row: 当前行
    // column: 当前列
    // rowIndex:当前行号
    // columnIndex :当前列号
    // 1代表:独占一行
    // 更大的自然数:代表合并了若干行
    // 0:代表“消失”的哪那一个单元格,后面的单元格向前推一格
    mergeCol(id, rowIndex) {
      debugger;
      // 合并单元格
      // id:属性名
      // rowIndex:行索引值
      var idName = this.TableData[rowIndex][id]; // 获取当前单元格的值
      if (rowIndex > 0) {
        // 判断是不是第一行
        // eslint-disable-next-line eqeqeq
        if (this.TableData[rowIndex][id] != this.TableData[rowIndex - 1][id]) {
          // 先判断当前单元格的值是不是和上一行的值相等
          var i = rowIndex;
          var num = 0; // 定义一个变量i,用于记录行索引值并进行循环,num用于计数
          while (i < this.TableData.length) {
            // 当索引值小于table的数组长度时,循环执行
            if (this.TableData[i][id] === idName) {
              // 判断循环的单元格的值是不是和当前行的值相等
              i++; // 如果相等,则索引值加1
              num++; // 合并的num计数加1
            } else {
              i = this.TableData.length; // 如果不相等,将索引值设置为table的数组长度,跳出循环
            }
          }
          return {
            rowspan: num, // 最终将合并的行数返回
            colspan: 1,
          };
        } else {
          return {
            rowspan: 0, // 如果相等,则将rowspan设置为0
            colspan: 1,
          };
        }
      } else {
        // 如果是第一行,则直接返回
        let i = rowIndex;
        let num = 0;
        while (i < this.TableData.length) {
          // 当索引值小于table的数组长度时,循环执行
          if (this.TableData[i][id] === idName) {
            i++;
            num++;
          } else {
            i = this.TableData.length;
          }
        }
        return {
          rowspan: num,
          colspan: 1,
        };
      }
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 合并单元格
      switch (
        columnIndex // 将列索引作为判断值
      ) {
        // 通过传递不同的列索引和需要合并的属性名,可以实现不同列的合并(索引0,1 指的是页面上的0,1)
        case 1:
          return this.mergeCol("gzTroubles", rowIndex);
        case 0:
          return this.mergeCol("gzID", rowIndex);
      }
    },
    //#endregion
  },
};
</script>

### 实现 `el-table` 合并单元并保持行有序号 在 Element UI 的 `el-table` 中,可以通过自定义方法来实现合并单元(merge cells),同时也可以通过计算属性或者额外逻辑来显示每行的序号。以下是具体实现方式: #### 1. 显示行号 为了给每一行添加序号,可以利用表的 `type="index"` 属性[^3] 或者通过作用域插槽(scope slot)来自定义序号列。 ```html <el-table :data="tableData" border> <!-- 使用 type="index" 自动生成序号 --> <el-table-column type="index" label="序号" width="80"></el-table-column> <!-- 自定义序号列 --> <el-table-column prop="name" label="名称"> <template #default="scope"> {{ scope.$index + 1 }}. {{ scope.row.name }} </template> </el-table-column> </el-table> ``` #### 2. 合并单元 要实现单元并功能,需使用 `span-method` 属性,并提供一个回调函数用于指定哪些单元应该被并。该回调函数接收四个参数:当前行索引、当前列索引、行数以及列数。 以下是一个完整的例子,展示如何基于相同的数据项自动并某些列中的单元: ```javascript <script setup> import { ref } from 'vue'; const tableData = ref([ { name: '张三', group: 'A' }, { name: '李四', group: 'A' }, { name: '王五', group: 'B' } ]); // 定义 spanMethod 方法 const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => { if (columnIndex === 1) { // 假设我们只希望对第2列进行并操作 const prevRow = tableData.value[rowIndex - 1]; if (rowIndex % 2 === 0 && prevRow.group === row.group) { return [0, 0]; // 当前行不显示 } else { let rowspanCount = 1; while ( tableData.value[rowIndex + rowspanCount]?.group === row.group && rowIndex + rowspanCount < tableData.value.length ) { rowspanCount++; } if (rowspanCount > 1) { return [rowspanCount, 1]; // 返回需要跨越的行数和列数 } } } }; </script> <template> <el-table :data="tableData" border :span-method="objectSpanMethod"> <el-table-column type="index" label="序号" width="80"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="group" label="组别"></el-table-column> </el-table> </template> ``` 在这个示例中,当相邻两行或多行具有相同的 `group` 字段时,它们会被视为同一组数据,在对应的列上会执行跨行并的操作[^4]。 #### 注意事项 - 如果表头也需要参与并,则需要单独处理。 - 数据量较大时,频繁调用 `span-method` 可能会影响性能,因此建议优化算法减少不必要的循环判断。 --- ###
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值