vue列表的动态合并

文章介绍了在使用ElementUI框架开发网页时,如何通过`span-method`属性实现表格中同一列数据的合并。提供了两种方法,一种是直接在`objectSpanMethod`中处理,另一种是通过`mergeTableRow`方法预先处理数据。这两种方法都能有效地解决不同人的项目数据合并问题。

方法一:单纯的把同一列数据合并,存在不同人的项目合并了,如下图第7和8行,推荐使用方法二:

绘制表格,使用element的span-method方法实现合并,并绑定:span-method=“objectSpanMethod”

 <el-table
          :data="tableData"
          border
          style="width: 100%"
          :span-method="objectSpanMethod"
        >
          <el-table-column label="序号" type="index" width="60">
          </el-table-column>
          <el-table-column prop="tester" label="姓名" width="120">
          </el-table-column>
          <!-- <el-table-column sortable prop="date" label="总数" width="120">
          </el-table-column> -->
          <el-table-column prop="project_name" label="项目" width="300">
          </el-table-column>
          <el-table-column prop="subsys_name" label="子系统" width="300">
          </el-table-column>
          <el-table-column prop="total" label="项目Bug数" width="160">
          </el-table-column>

methods中objectSpanMethod通过指定字段进行合并;

    //封装合并列
    mergeCol(id, rowIndex) {
      //合并单元格
      //id:属性名
      //rowIndex:行索引值
      //获取当前单元格
      var idName = this.tableData[rowIndex][id];
      //判断是不是第一行
      if (rowIndex > 0) {
        //先判断当前单元格的值是不是和上一行的值相等
        if (this.tableData[rowIndex][id] != this.tableData[rowIndex - 1][id]) {
          //i记录行索引值并循环,num用于计数
          var i = rowIndex;
          var num = 0;
          console.log(this.tableData[i][id], idName);
          //当索引值小余table数组长度时,循环执行
          while (i < this.tableData.length) {
            //判断循环的单元格的值是不是和当前行的值相等
            if (this.tableData[i][id] === idName) {
              //如果相等,索引值加1,合并的num计数加1
              i++;
              num++;
            } else {
              //如果不相等,将索引值设置为table的数组长度,跳槽循环
              i = this.tableData.length;
            }
          }
          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) {
          //判断循环的单元格的值是不是和当前行的值相等
          if (this.tableData[i][id] === idName) {
            //如果相等,索引值加1,合并的num计数加1
            i++;
            num++;
          } else {
            //如果不相等,将索引值设置为table的数组长度,跳槽循环
            i = this.tableData.length;
          }
        }
        return {
          //返回最终的合并行数
          rowspan: num,
          colspan: 1,
        };
      }
    },

    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      //合并单元格
      switch (
        //将列索引值作为判断值
        columnIndex
      ) {
        //通过传递不同的列索引和需要合并的属性名,可以实现不同列的合并
        case 1:
          return this.mergeCol("tester", rowIndex);
        case 2:
          return this.mergeCol("project_name", rowIndex);
        case 3:
          return this.mergeCol("subsys_name", rowIndex);
        // case 4:
        //   return this.mergeCol("tester", rowIndex);
      }
    },

方法二:规避了方法一中的问题;

 methods中

    // 合并表格
    mergeTableRow(data, merge) {
      if (!merge || merge.length === 0) {
        return data;
      }
      merge.forEach((m) => {
        const mList = {};
        let spliceLocation = merge.indexOf(m);
        data = data.map((v, index) => {
          const rowVal = v[m];
          if (mList[rowVal] && mList[rowVal].newIndex === index) {
            // flag为true的时候代表当前值的前者与上一个值相等
            /*
                只有当当前merge之前的所有merge的值的当前index等于index-1  才允许当前merge合并
            */
            let flag = false;
            let mergeSolve = merge.slice(0, spliceLocation);
            mergeSolve.slice(0, spliceLocation).forEach((mergeItem) => {
              if (data[index][mergeItem] == data[index - 1][mergeItem]) {
                flag = true;
              }
            });
            if (m == merge[0]) {
              flag = true;
            }
            if (flag) {
              mList[rowVal]["num"]++;
              mList[rowVal]["newIndex"]++;
              data[mList[rowVal]["index"]][m + "-span"].rowspan++;
              v[m + "-span"] = {
                rowspan: 0,
                colspan: 0,
              };
            } else {
              mList[rowVal] = {
                num: 1,
                index: index,
                newIndex: index + 1,
              };
              v[m + "-span"] = {
                rowspan: 1,
                colspan: 1,
              };
            }
          } else {
            mList[rowVal] = {
              num: 1,
              index: index,
              newIndex: index + 1,
            };
            v[m + "-span"] = {
              rowspan: 1,
              colspan: 1,
            };
          }
          return v;
        });
      });
      return data;
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      const span = column["property"] + "-span";
      if (row[span]) {
        return row[span];
      }
    },

调用mergeTableRow方法,指定合并单元格的字段;

defect
      .personProjectSubsysBugCreateTotal({
        project_id: [],
        creator: [],
        date_create_time_start: "",
        date_create_time_end: "",
        severity: [],
      })
      .then((res) => {
        if (res.code == 200) {
          this.total = res.data.total;
          //后端传输过来的数据
          let dataArr = res.data.person_bug_list;
          let dataSolve = this.mergeTableRow(dataArr, [
            "tester",
            "project_name",
            "subsys_name",
          ]);
          this.tableData = dataSolve;
        } else {
          this.$message.error(data.message);
        }
      })
      .catch((error) => {
        this.$message.error(error);
      });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值