vue+iview架构实现动态合并单元格

很多项目中出现相同属性的行数合并的问题,如图

实现如下:

html:

<Table :columns="columns" :data="tableData" border :span-method="handleSpan"></Table>

 js:

定义要合并的单元格行数或者列数

handleSpan ({ row, column, rowIndex, columnIndex }) {
      // 合并第2列,这里columnIndex==1,根据需求的不同,写在前端,若合并第1列,这里columnIndex==0
      if (columnIndex === 1) {
        // 计算合并的行数列数
        let x = row.mergeColumn === 0 ? 0 : row.mergeColumn
        let y = row.mergeColumn === 0 ? 0 : 1
        return [x, y]
      }
    }

实现方法,我这里要合并的字段是staff_no,可以按需更改,在获取列表数据那里调用assembleData()方法,把数组传过去

assembleData (data) {
      let names = []
      // 筛选出不重复的 staff_no值,将其放到 names数组中
      data.forEach(e => {
        if (!names.includes(e.staff_no)) {
          names.push(e.staff_no)
        }
      })
      let nameNums = []
      // 将names数组中的 staff_no值设置默认合并0个单元格,放到 nameNums中
      names.forEach(e => {
        nameNums.push({ staff_no: e, num: 0 })
      })
      // 计算每种 staff_no值所在行需要合并的单元格数
      data.forEach(e => {
        nameNums.forEach(n => {
          if (e.staff_no === n.staff_no) {
            n.num++
          }
        })
      })
      // 将计算后的合并单元格数整合到 data中
      data.forEach(e => {
        nameNums.forEach(n => {
          if (e.staff_no === n.staff_no) {
            if (names.includes(e.staff_no)) {
              e.mergeColumn = n.num
              // 删除已经设置过的值(防止被合并的单元格进到这个 if 语句中)
              names.splice(names.indexOf(n.staff_no), 1)
            } else {
              // 被合并的单元格设置为 0
              e.mergeColumn = 0
            }
          }
        })
      })
      // 将整理后的数据交给表格渲染
      this.tableData = data
    },

这样的话就实现了单元格的合并但是会出现一个问题,如果要合并的行数不在相邻行就会出现串行的问题,这样就需要手动处理一下后端返回的数据,遍历一下,把相同属性值的行数放在一起:

checkSameData (tableData) {
      let cache = {} // 存储的是键是staff_no的值,值是staff_no在indeces中数组的下标
      let indices = [] // 数组中每一个值是一个数组,数组中的每一个元素是原数组中相同staff_no的下标
      tableData.map((item, index) => {
        // eslint-disable-next-line camelcase
        let staff_no = item.staff_no
        let _index = cache[staff_no]
        if (_index !== undefined) {
          indices[_index].push(index)
        } else {
          cache[staff_no] = indices.length
          indices.push([index])
        }
      })
      let result = []
      indices.map((item) => {
        item.map((index) => {
          result.push(tableData[index])
        })
      })
      this.tableData = result
    },

这样在获取数据成功那里调用上面两个方法就可以了

 搞定,欢迎指点。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值