el-table合并行

借鉴了小谷69同学的帖子,又根据自己的需求进行了调整。

 需求为:序号根据业务id合并,合并后的业务数据再根据时间进行二次合并。

一、准备两个变量

data() {
    return {
      // 合并行
      mergeArr: [],
      // 排序号
      indexNum: {},
    }
}

二、准备合并行方法

    colMethod(columnArr, data) {
      // columnArr 合并行所在的列字段
      // data 需要合并的表格数据
      let column = {}
      let position = 0
      // 遍历合并的列数据
      columnArr.forEach((prop) => {
        column[prop] = []
        //  遍历合并的行数据
        data.forEach((row, rowIndex) => {
          // 第N列第一行
          column[prop][rowIndex] = [1, 1]
          if (rowIndex === 0) {
            // 记录当前行号
            position = 0
          } else if (row[prop] === data[rowIndex - 1][prop]) {
            // 当前行数据等于上一行,根据记录的行号,计算需要合并几行。
            column[prop][position][0] += 1
            // 当前行 隐藏不显示
            column[prop][rowIndex][0] = 0
          } else {
            // 不相等之后,重置记录行号
            position = rowIndex
          }
        })
      })
      return column
    }

三、准备表格调用的合并方法 :span-method="objectSpanMethod

    // 表格调用的合并方法
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      let arr = this.mergeArr[column.property] || []
      if (column.type == 'index' && this.mergeArr['id'])
        return this.mergeArr['id'][rowIndex]
      else if (arr.length) return arr[rowIndex]
      else[1, 1]
    },

四、合并逻辑

    getList() {
        const _this = this;
        // 计算合并的行
        this.mergeArr = this.colMethod(['id'], this.reportList)
        // 浅拷贝处理数据
        let dataBase = Array.from(this.reportList);
        let saleIdArr = this.colMethod(['id'], dataBase)

        // 先根据saleId合并第一次,将数据源根据合并下标处理为多段数据源
        let newData = []
        saleIdArr.saleId.forEach( (item, index) => {
          if (item[0] > 0) {
            let res = []
            for (let i = 0; i < item[0]; i++) {
              res.push(dataBase.slice(0,1)[0])
              this.$delete(dataBase, 0)
            }
            newData.push(res)
          }
        })

        // 根据合并后的数据,分段处理time的合并行下标
        let outArr = []
        for (let i = 0; i < newData.length; i++) {
          let obt = _this.colMethod(['time'], newData[i]);
          if (obt.outboundTime.length > 0) {
            outArr.push(obt.outboundTime)
          }
        }
        
        // 处理time合并行
        let finishRes = []
        outArr.forEach( item => {
          if (item.length > 1) {
            for (let i = 0; i < item.length; i++) {
              finishRes.push(item[i])
            }
          } else {
            finishRes.push(item[0])
          }
        })
        // 赋值给总合并行集合
        this.mergeArr.outboundTime = finishRes
        
        //排列序号
        this.indexObj() 

    }
    // 排列序号
    indexObj() {
      let num = 0;
      this.mergeArr['id'].forEach((item, index) => {
        if (item[0] != 0) {
          this.indexNum[index] = num += 1
        }
      })
    },
<el-table-column label="序号" align="center" width="55" type="index" 
:resizable="false" :index="indexMethod" />
    

五、处理排序

<el-table-column label="序号" align="center" width="55" type="index" 
:resizable="false" :index="indexMethod" />
    
    // 排列序号
    indexObj() {
      let num = 0;
      this.mergeArr['id'].forEach((item, index) => {
        if (item[0] != 0) {
          this.indexNum[index] = num += 1
        }
      })
    },
    // 自定义序号
    indexMethod(index) {
      return this.indexNum[index]
    },

借鉴文章el-table表格的行合并以及合并后序号的处理_elementui表格合并行序号出错_小谷69的博客-CSDN博客

 附加:原生table合并行

需求不变,因打印功能,el-table适配性不好,改为原生table布局,合并行要素为rowspan,所以在遍历数据时要分开控制rowspan,同理根据业务id分段数据源,分别处理各自的time合并行

<tr v-for="(item, index) in reportList" :key="index" class="text-center">
    <td style="width: 60px" v-if="item.rowspan > 0" :rowspan="item.rowspan">{{ item.orderList }}</td>
    <td style="width: 150px" v-if="item.rowspans > 0" :rowspan="item.rowspans">{{ item.time }}</td>
</tr>

    getList() {
        // 根据saleId计算合并的行
        let saleIdSpan = this.getSpanArrN(this.reportList, 'id')
        let orderList = 1
        saleIdSpan.forEach((item, index) => {
          this.reportList[index].rowspan = item
          this.reportList[index].orderList = item > 0 ? orderList++ : orderList
        })

        // 浅拷贝表格数据,用于分段截取
        let dataBase = Array.from(this.reportList);

        // 先根据saleId一级合并行,将数据源根据合并下标处理为多段数据源
        let newData = []
        saleIdSpan.forEach( (item, index) => {
          if (item > 0) {
            let res = []
            for (let i = 0; i < item; i++) {
              res.push(dataBase.slice(0,1)[0])
              this.$delete(dataBase, 0)
            }
            newData.push(res)
          }
        })

        // 根据合并后的数据,分段处理outboundTime的合并行下标
        let outArr = []
        for (let i = 0; i < newData.length; i++) {
          let obt = this.getSpanArrN(newData[i], 'time')
          outArr = outArr.concat(obt)
        }
        // 赋值outboundTime合并行
        outArr.forEach((item, index) => {
          this.reportList[index].rowspans = item
        })
    },
    getSpanArrN(data, prop) {
      let count = 0; // 用来记录需要合并行的起始位置
      let mergeObj = []
      data.forEach((item, index) => {
        if (index === 0) {
          mergeObj.push(1);
        } else {
          if (item[prop] === data[index - 1][prop]) {
            mergeObj[count] += 1;
            mergeObj.push(0);
          } else {
            count = index;
            mergeObj.push(1);
          }
        }
      })
      return mergeObj
    }

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值