element中table动态合并行合并列

4,181 阅读1分钟

背景介绍

前两天刚好有个朋友问我element-ui里面的table合并问题,她说没有太看懂官网的示例,想着刚开始合并的表格的时候也是花了一些时间才明白滴,所以我想着刚好整理一下,方便自己也方便有需要的朋友们。

参数理解

官方解释:通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspancolspan的对象。

相关场景

多行或多列共用一个数据时,可以合并行或列。

一、动态合并行(上下行)

合并第一列名称相同的行

<script>
  export default {
    data() {
      return {
        tableData: [
          {
            id: "12987122",
            name: "王小虎",
            amount1: "234",
            amount2: "3.2",
            amount3: 10,
          },
          {
            id: "12987123",
            name: "王二丫",
            amount1: "444",
            amount2: "4.43",
            amount3: 12,
          },
          {
            id: "12987124",
            name: "王二丫",
            amount1: "444",
            amount2: "1.9",
            amount3: 9,
          },
          {
            id: "12987125",
            name: "小西瓜",
            amount1: "621",
            amount2: "2.2",
            amount3: 17,
          },
          {
            id: "12987126",
            name: "小西瓜",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
          {
            id: "12987127",
            name: "小西瓜",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
          {
            id: "12987128",
            name: "小菜鸟",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
        ],
        spanArr: []
      };
    },
    created() {
      this.getSpanArr(this.tableData);
    },
    methods: {
      /**
       * @description 👇合并行的计算方法
       * @param {array} data 数据列表
       */
      getSpanArr(data) {
        this.spanArr = [] // tip: 后台获取完成数据后,一定要重置spanArr=[],避免出现合并混乱!!!!!
        for (let i = 0; i < data.length; i++) {
          // 当为第一行时
          if (i === 0) {
            this.spanArr.push(1); 
            this.pos = 0; 
          } else {
            // 判断当前值是否与上一行的【名称】相等,相等则进行合并
            if (data[i].name === data[i - 1].name) {
              this.spanArr[this.pos] += 1; // 合并单元格:合并的行数 +1
              this.spanArr.push(0); // 0代表单元格是不需要显示, 已经被合并的单元格
            } else {
              this.spanArr.push(1); // 1代表当前这行的数据需要被显示
              this.pos = i; 
            }
          }
        }
      },
      // 👇合并列
      objectSpanMethod({ row, column, rowIndex, columnIndex }) {
        // 用于设置要合并的列(这里是指第一列合并)
        if (columnIndex === 1) {
          const _row = this.spanArr[rowIndex]; // 合并行数
          const _col = this.spanArr[rowIndex] > 0 ? 1 : 0; // 合并的列数
          return {
            rowspan: _row,
            colspan: _col,
          };
        }
      },
    },
  };
</script>

效果图

image.png

👇当前示例有几个参数说明:

spanArr: 数组类型,用来存放每一行记录的合并数量。比如当前示例的数据,行的合并数量显示就是[1, 2, 0, 3, 0, 0, 1],第1行为1代表与占一行;第2行为2代表占2行;第3行为0,因为要向上与第2行合并...以此类推

pos:数字类型,临时存放当前需要显示的单元格索引,当前示例中,pos的索引值依次出现是0,1, 3,6,也就是第1行,第2行,第4行,第7行需要显示单元格。

二、动态合并列(左右列)

合并第3列和第4列金额相同的列。

<script>
  export default {
    data() {
      return {
        tableData: [
          {
            id: "12987122",
            name: "王小虎",
            amount1: "234",
            amount2: "3.2",
            amount3: 10,
          },
          {
            id: "12987123",
            name: "王二丫",
            amount1: "444",
            amount2: "444",
            amount3: 12,
          },
          {
            id: "12987124",
            name: "王二丫",
            amount1: "444",
            amount2: "1.9",
            amount3: 9,
          },
          {
            id: "12987125",
            name: "小西瓜",
            amount1: "666",
            amount2: "666",
            amount3: 17,
          },
          {
            id: "12987126",
            name: "小西瓜",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
          {
            id: "12987127",
            name: "小西瓜",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
          {
            id: "12987128",
            name: "小菜鸟",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
        ],
        spanArr: []
      };
    },
    created() {
    },
    methods: {
      // 👇合并列 (示例:第3列和第4列如果【金额】相等就合并)
      arraySpanMethod({ row, column, rowIndex, columnIndex }) {
        if (columnIndex === 2 || columnIndex ===3) { // 列索引为 第2列时或第3列时
          if (row.amount1 === row.amount2) {
            return [1, 2] // [行跨度,列跨度 ]
          }
        }
      }
    },
  };
</script>

效果图

image.png

三、动态合并行和列(完整代码)

<template>
  <div>
    <el-table
      :data="tableData"
      :span-method="arraySpanMethod"
      border
      style="width: 100%; margin-top: 20px"
      :header-cell-style="{ background: '#f9f9f9', color: '#323232' }"
    >
      <el-table-column prop="id" label="ID" width="180"> </el-table-column>
      <el-table-column prop="name" label="姓名"> </el-table-column>
      <el-table-column prop="amount1" label="数值 1(元)"> </el-table-column>
      <el-table-column prop="amount2" label="数值 2(元)"> </el-table-column>
      <el-table-column prop="amount3" label="数值 3(元)"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        tableData: [
          {
            id: "12987122",
            name: "王小虎",
            amount1: "234",
            amount2: "3.2",
            amount3: 10,
          },
          {
            id: "12987123",
            name: "王二丫",
            amount1: "444",
            amount2: "444",
            amount3: 12,
          },
          {
            id: "12987124",
            name: "王二丫",
            amount1: "444",
            amount2: "1.9",
            amount3: 9,
          },
          {
            id: "12987125",
            name: "小西瓜",
            amount1: "666",
            amount2: "666",
            amount3: 17,
          },
          {
            id: "12987126",
            name: "小西瓜",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
          {
            id: "12987127",
            name: "小西瓜",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
          {
            id: "12987128",
            name: "小菜鸟",
            amount1: "539",
            amount2: "4.1",
            amount3: 15,
          },
        ],
        spanArr: []
      };
    },
    created() {
      this.getSpanArr(this.tableData);
      // this.getArraySpan(this.tableData);
    },
    methods: {
      /**
       * @description 👇合并行的计算方法
       * @param {array} data 数据列表
       */
      getSpanArr(data) {
        this.spanArr = [] // tip: 后台获取完成数据后,一定要重置spanArr,避免出现合并混乱!!!!!
        for (let i = 0; i < data.length; i++) {
          // 当为第一行时
          if (i === 0) {
            this.spanArr.push(1); // 1:独自占一行
            this.pos = 0; // 合并的起始行
          } else {
            // 判断当前值是否与上一行的值相等,相等则进行合并
            if (data[i].name === data[i - 1].name) {
              this.spanArr[this.pos] += 1; // 合并单元格:合并的行数 +1
              this.spanArr.push(0); // 0代表单元格是不需要显示, 已经被合并的单元格
            } else {
              this.spanArr.push(1); // 1代表当前这行的数据需要被显示
             
              this.pos = i; // 存放需要合并行的索引
              console.log(this.pos); 
            }
          }
        }
      },
      // 👇合并行和列 示例:第1列的“行”合并 & 第3列和第4列如果金额相等就“列”合并
      arraySpanMethod({ row, column, rowIndex, columnIndex }) {
        // 合并列方法
        if (columnIndex === 2 || columnIndex ===3) { // 列索引为 第2列时或第3列时
          if (row.amount1 === row.amount2) {
            return [1, 2] // [行跨度,列跨度 ]
          }
        }
        // 合并行方法:用于设置要合并的列(这里是指第一列合并)
        if (columnIndex === 1) {
          const _row = this.spanArr[rowIndex]; // 合并行数
          const _col = this.spanArr[rowIndex] > 0 ? 1 : 0; // 0:不显示
          return {
            rowspan: _row,
            colspan: _col,
          };
        }
      }
    },
  };
</script>


效果图

image.png