vue列表动态合并

两种方法,各取所需,最后的效果图是不同的

第一种

 
methods: {
 getAllInfo() {
            getAllInfos(this.queryParams).then(response => {
                // console.log(response.rows)
                this.loading = false//遮罩层
                let dataArr = response.rows//后端传输过来的数据
                 let dataSolve = this.mergeTableRow(dataArr, ["合并字段一", "合并字段二", "合并字段三", "合并字段四"...]);
                 this.tableData = dataSolve;
            }).catch(err => {
                console.log(err)
            })
        },
    // 合并表格
    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];
      }
    },
  },

 

第二种(比第一种麻烦),因为每次合并都需要swich去匹配的,这时如果已经写好的字段顺序发生改变,case的值也就需要我们去改变,合并的字段少还好,如果字段多的话就会很麻烦,所以还是推荐第一种

   methods: {
     getAllInfo() {
            getAllInfos(this.queryParams).then(response => {
                // console.log(response.rows)
                this.loading = false
                this.tableData = response.rows
                
            }).catch(err => {
                console.log(err)
            })
        },
 mergeCol(id, rowIndex) { // 合并单元格
            // id:属性名
            // rowIndex:行索引值
            let idName = this.tableData[rowIndex][id] // 获取当前单元格的值
            if (rowIndex > 0) { // 判断是不是第一行
                // eslint-disable-next-line eqeqeq
                if (this.tableData[rowIndex][id] != this.tableData[rowIndex - 1][id]) { // 先判断当前单元格的值是不是和上一行的值相等
                    let i = rowIndex;
                    let 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 }) { // 合并单元格
            // console.log(columnIndex)
            switch (columnIndex) { // 将列索引作为判断值
                // 通过传递不同的列索引和需要合并的属性名,可以实现不同列的合并
                case 0:
                    return this.mergeCol('字段一', rowIndex)
                    break;
                case 1:
                    return this.mergeCol('字段二', rowIndex)
                    break;
                case 2:
                    return this.mergeCol('字段三', rowIndex)
                    break;
                
                default:
                    break;
            }
        },
}

两种效果图对比

第一种

第二种

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值