Vue+ElementUI实现table表格动态合并

**本篇博客主要记录个人在开发过程中遇到的难点问题,万分期待大家的讨论以及弥补短缺之处!**

首先看看elementui提供的table组件,直达【官网】

**文档说明**

官方文档中指出el-table组件接收一个"span-method"属性,属性值是一个回调函数,四个参数分别返回当前行、列、行号、列号,该回调函数需返回合携带rowspan、colspan的一组对象!

      objectSpanMethod({ row, column, rowIndex, columnIndex }) {
        if (columnIndex === 0) {       //判断是否为第一列数据
          if (rowIndex % 2 === 0) {    //判断开始合并的行号
            return {
              rowspan: 2,
              colspan: 1
            };
          } else {
            return {
              rowspan: 0,
              colspan: 0
            };
          }
        }
      }

显而易见、eltable组件每执行一次渲染就会调用一次objectSpanMethod方法,该方法返回合并对象,但是根据行号进行合并单元格确实不符合开发逻辑,一般我们都是根据后端返回的数据进行合并,百撕不得骑姐 只好向度娘服了软,经过两天研究总算是山重水复疑无路、柳暗花明又一村啊;

-----------------------------
具体思路:created钩子时根据后端返回的数据遍历出每一行在合并的时候需要合并的行数,把这些数据记录在data里面,合并的时候根据合成的记录进行合并!

------data数据      
      spanArr1: [],       //存放每一行记录的合并数
      position1: 0        // spanArr1 的索引

-------methods方法
 GetSpanArr() {
      var data = this.tableData;     
      data.forEach((element, index) => {    //遍历数据 得到每项 和下标
        if (index === 0) {                  //如果是一条数据 直接不合并
          this.spanArr1.push(1);            //记录合并数
          this.position = 0;                //记录spanArr1的索引值
        } else {
          if (element.One === data[index - 1].One) {      //非第一条数据 则判断是否与上一条相邻的数据值相等
            this.spanArr1[this.position1] += 1;           //相等则说明需要合并 rousoan:2 = 合并一行
            this.spanArr1.push(0);                        //记录索引
          } else {
            this.spanArr1.push(1);                        //与上一单元格数据不相等 则不合并 rowspan:1 = 不合并
            this.position1 = index;                       //记录索引
          }
        }
      });

详解:this.tabdata是el-table接收的数组(后端返回的数据),遍历之后拿到每一条对象、索引,根据索引判断当前是哪一条数据第一条无需合并,因为合并条件是当前数据与上一条数据的对象某一个属性值是否相等,第一条没有上一条则直接不合并,索引记录为0,若不是第一条数据(index!==0)则判断One这个属性与上一条数据(index-1)的One属性值是否相等,相等则在记录的数组spanArr1中第position1个属性值的基础上+=1 ,若与上提条数据相比 值不相等,则说明不合并,那么push1 ,1为不合并,0为该行不显示!

    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 1) {            //判断是否是第一行
        const _row = this.spanArr1[rowIndex]; 
        const _col = _row > 0 ? 1 : 0;    //1为不合并 0为合并至最后一列
        return {                          //返回需要合并的对象
          rowspan: _row,
          colspan: _col
        };
      }
    },

之后在组件el-table的span-method属性绑定objectSpanMethod方法!

PS:上述方法只是针对于合并第一行数据,若需要合并第二行数据,由于是每行判断条件不一样,则无法判断到第二行数据,目前采用笨办法,如下示例:

-------data数据
      spanArr1: [],         //存放每一行记录的合并数
      spanArr2: [],         //存放每二行合并数
      position1: 0,         // spanArr1 的索引
      position2: 0          // spanArr2 的索引

-------methods方法
//回调
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 1) {            //判断是否是第一行
        const _row = this.spanArr1[rowIndex]; 
        const _col = _row > 0 ? 1 : 0;    //1为不合并 0为合并至最后一列
        return {
          rowspan: _row,
          colspan: _col
        };
      }
      if (columnIndex === 2) {            //判断是否是第一行
        const _row = this.spanArr2[rowIndex]; 
        const _col = _row > 0 ? 1 : 0;    //1为不合并 0为合并至最后一列
        return {
          rowspan: _row,
          colspan: _col
        };
      }
    },

//处理数据
GetSpanArr() {
      var data = this.tableData;     
      data.forEach((element, index) => {    //遍历数据 得到每项 和下标
        if (index === 0) {                  //如果是一条数据 直接不合并
          this.spanArr1.push(1);            //记录合并数
          this.spanArr2.push(1);            //记录合并数
          this.position1 = 0;                //记录spanArr1的索引值
          this.position2 = 0;                //记录spanArr2的索引值
        } else {
          if (element.One === data[index - 1].One) {      //非第一条数据 则判断是否与上一条相邻的数据值相等
            this.spanArr1[this.position1] += 1;           //相等则说明需要合并 rousoan:2 = 合并一行
            this.spanArr1.push(0);                        //记录索引
          } else {
            this.spanArr1.push(1);                        //与上一单元格数据不相等 则不合并 rowspan:1 = 不合并
            this.position1 = index;                       //记录索引
          }
          if (element.Two === data[index - 1].Two) {      //非第一条数据 则判断是否与上一条相邻的数据值相等
            this.spanArr2[this.position2] += 1;           //相等则说明需要合并 rousoan:2 = 合并一行
            this.spanArr2.push(0);                        //记录索引
          } else {
            this.spanArr2.push(1);                        //与上一单元格数据不相等 则不合并 rowspan:1 = 不合并
            this.position2 = index;                       //记录索引
          }
        }
      });

模拟数据结构:

tableData: [
        {
          Zero: "",
          One: "星期一",
          Two: "星期二",
          Three: "周三",
          For: "周四",
          Five: "周五",
          Six: "周六",
          Seven: "周日"
        },
        {
          Zero: "课时 1",
          One: "语文",
          Two: "体育",
          Three: "",
          For: ""
        },
        {
          Zero: "课时 2",
          One: "语文",
          Two: "体育",
          Three: "",
          For: ""
        },
        {
          Zero: "课时 3",
          One: "语文",
          Two: "数学",
          Three: "",
          For: ""
        },
        {
          Zero: "课时 4",
          One: "地理",
          Two: "生物",
          Three: "",
          For: ""
        }
      ],

-----------期待下次更新-----------

发布了17 篇原创文章 · 获赞 76 · 访问量 9664

猜你喜欢

转载自blog.csdn.net/qq_43471802/article/details/100020693