el-table合并单元格如何实现包含与被包含的关系

合并单元格,列存在包含与被包含关系

image.png

如图,支付场景为第一序列,支付产品存在与支付场景下,而APPID有存在与支付产品下,场景>产品>APPID

思路

1.初始化数据阶段,对数据进行添加需要合并的参数和标识

  • =合并第一列=
  • 首要知道需要合并第一列相同属性sceneId,开始遍历数组
  • 找到相同的sceneId,是否已经有一项有sceneIdStart属性
  • 没有的情况下,在当前项,添加sceneIdStart属性为当前索引,并且计算有多少个相同的sceneId,并复制给当前项的sceneIdNum
  • =合并第二列=
  • 首要知道需要合并第二列相同属性productValue,他是包含在,第一列,相同的sceneId中,开始遍历数组
  • 遍历过程中,判断当前项是否有sceneIdNum,
  • 有的情况下,使用slice(item.sceneIdStart, item.sceneIdStart + item.sceneIdNum),浅拷贝该数组,赋值给sceneIdStartArr,这个新数组就是包含相同的sceneId数据(利用slice浅拷贝,属性为对象会影响到源数据的特性)(后续需要修改的内容也是这里的,后续流程其实是在走合并第一列的流程)
  • 开始遍历sceneIdStartArr数组,找到相同的productValue,并且是否已经有一项有productValueStart属性
  • 没有的情况下,在当前项,添加sceneIdStart属性为当前索引,并且计算有多少个相同的productValue,并赋值给当前项的productValueNum
  • =合并第三列=(和合并第二列逻辑一样)
  • 首要知道需要合并第二列相同属性APPID,他是包含在,第二列,相同的productValue中,开始遍历数组
  • 遍历过程中,判断当前项是否有productValueNum,
  • 有的情况下,使用slice(item.productValueStart, item.productValueStart + item.productValueNum),浅拷贝该数组,赋值给productValueStartArr,这个新数组就是包含相同的productValue数据
  • 开始遍历productValueStartArr数组,找到相同的APPID,并且是否已经有一项有APPIDStart属性
  • 没有的情况下,在当前项,添加APPIDStart属性为当前索引,并且计算有多少个相同的APPID,并赋值给当前项的APPIDNum

2.el-tabel,调用span-method=“objectSpanMethod”,在该方法中,只要判断第几列,需要用到特定的参数或标识

  • objectSpanMethod存在四个参数({ row, column, rowIndex, columnIndex })
  • 判断是否为第一列,columnIndex === 0,判断当前数据是否包含sceneIdNum属性,有的话添加
if (row.sceneIdNum) {
          return {
            rowspan: row.sceneIdNum,
            colspan: 1,
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          }
        }
  • 后续第二例和,第三列同样操作

  • 初始化计算的好处:减少了在el-tabel实时计算

代码展示

  • 步骤一
/* **
     * @title 合并单元格列: 需要合并的属性
     * @param { String|Number } sceneId 支付场景
     * @param { String } productValue 支付产品
     * @param { String|Number } APPID APPID
     */
    infodata() {
      //  1.合并sceneId 支付场景
      this.tableData.forEach((item, index, arr) => {
        item.index = index
        // 1.判断 数组中是否有相同的sceneId 和 sceneIdStart
        const isSceneIdAndStart = arr.some((v) => {
          return v.sceneId === item.sceneId && v.hasOwnProperty('sceneIdStart')
        })
        // 2. 如果没有进行对当前id计算,则进行计算和赋值
        if (!isSceneIdAndStart) {
          // 用来计算sceneId 的个数
          const sceneNum = arr.reduce((accumulator, currentValue) => {
            const isVal = currentValue.sceneId === item.sceneId ? 1 : 0
            return accumulator + isVal
          }, 0)
          item.sceneIdStart = index
          item.sceneIdNum = sceneNum
        }
      })

      // 2.合并 APPID APPID
      this.tableData.forEach((item, index, arr) => {
        // 1.判断 数组中是否有相同的sceneId 的sceneIdNum
        if (item.hasOwnProperty('sceneIdNum')) {
          // 2.合并一组相同的数据,并且判断当前合并数组是否有相同的productValueStart
          const sceneIdStartArr = arr.slice(item.sceneIdStart, item.sceneIdStart + item.sceneIdNum)
          sceneIdStartArr.forEach((d, k, n) => {
            const isProductValueAndStart = n.some((v) => {
              return d.productValue === v.productValue && v.hasOwnProperty('productValueStart')
            })
            // 3. 如果没有进行对当前isProductValueAndStart,则进行计算和赋值
            if (!isProductValueAndStart) {
              const productValueNum = n.reduce((accumulator, currentValue) => {
                const isVal = currentValue.productValue === d.productValue ? 1 : 0
                return accumulator + isVal
              }, 0)
              d.productValueStart = d.index
              d.productValueNum = productValueNum
              // console.log('d', d)
            }
          })
        }
      })

      // 3.合并 APPID
      this.tableData.forEach((item, index, arr) => {
        // 1.判断 数组中是否有的productValueNum
        if (item.hasOwnProperty('productValueNum')) {
          // 2.合并一组相同的数据,并且判断当前合并数组是否有相同的productValueStart,利用slice浅拷贝缺陷
          const productValueStartArr = arr.slice(
            item.productValueStart,
            item.productValueStart + item.productValueNum,
          )
          productValueStartArr.forEach((d, k, n) => {
            const isAPPIDAndStart = n.some((v) => {
              return d.APPID === v.APPID && v.hasOwnProperty('APPIDStart')
            })
            // 3. 如果没有进行对当前isProductValueAndStart,则进行计算和赋值
            if (!isAPPIDAndStart) {
              const APPIDNum = n.reduce((accumulator, currentValue) => {
                const isVal = currentValue.APPID === d.APPID ? 1 : 0
                return accumulator + isVal
              }, 0)
              d.APPIDStart = d.index
              d.APPIDNum = APPIDNum
              // console.log('d', d)
            }
          })
        }
      })
    },
  • 步骤二
<el-table :data="tableData" :span-method="objectSpanMethod" border style="width: 100%"></el-table>


objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 第一列合并
      if (columnIndex === 0) {
        if (row.sceneIdNum) {
          return {
            rowspan: row.sceneIdNum,
            colspan: 1,
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          }
        }
      }
      // 第二列合并
      if (columnIndex === 1) {
        if (row.productValueNum) {
          return {
            rowspan: row.productValueNum,
            colspan: 1,
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          }
        }
      }
      // 第三列合并
      if (columnIndex === 2) {
        if (row.APPIDNum) {
          return {
            rowspan: row.APPIDNum,
            colspan: 1,
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          }
        }
      }
    },
  • 数据源
{
    "tableData": [
        {
            "scene": "demo1",
            "sceneId": "1499411749324066816",
            "product": "微信付款码",
            "productValue": "wx_bar",
            "APPID": "12987122",
            "channel": "微信",
            "weight": "1",
            "mchnum": 10
        },
        {
            "scene": "demo1",
            "sceneId": "1499411749324066816",
            "product": "微信付款码",
            "productValue": "wx_bar",
            "APPID": "12987122",
            "channel": "第三方服务商",
            "weight": "1",
            "mchnum": 10
        },
        {
            "scene": "demo1",
            "sceneId": "1499411749324066816",
            "product": "支付宝付款码",
            "productValue": "ali_bar",
            "APPID": "12987122",
            "channel": "第三方服务商",
            "weight": "1",
            "mchnum": 10
        },
        {
            "scene": "demo2",
            "sceneId": "1499411585939148800",
            "product": "微信小程序",
            "productValue": "wx_lite",
            "APPID": "12987124",
            "channel": "微信",
            "weight": "1",
            "mchnum": 10
        },
        {
            "scene": "demo2",
            "sceneId": "1499411585939148800",
            "product": "微信小程序",
            "productValue": "wx_lite",
            "APPID": "12987122",
            "channel": "第三方服务商",
            "weight": "1",
            "mchnum": 10
        }
    ]
}

样式优化-自定义指令

export const eltablebacknode = Vue => {
  // el-table 合并单元格背景色
  // v-backnode='"{ length: 6, merge: 3 }"' 表格每行应6列,合并列为3列
  Vue.directive('backnode', {
    bind: function (el, binding) {
      // console.log('el, binding', el, binding)
      const length = binding.value.length
      const merge = binding.value.merge
      const residue = length - merge // 抛去需要合并的列单元格 其余剩余内容
      Vue.nextTick(() => {
        let tbody = el.querySelector('.el-table__body tbody')
        let trAll = Array.from(tbody.querySelectorAll('tr'))
        // console.log('trAll', trAll[0])
        trAll.forEach(row => {
          const childNodes = row.childNodes
          const rowResidue = childNodes.length - residue // 当前行有多少合并单元格
          // console.log(childNodes.length, residue);
          if (childNodes.length > residue) {
            childNodes.forEach((v, i) => {
              // console.log('i < rowResidue', i < rowResidue);
              if (i < rowResidue) {
                v.classList.add('tdbackBack')
              }
            })
          }
          console.log('row', childNodes)
        })
      })
    },
  })
}
.el-table__body tbody .el-table__row td.tdbackBack{
  background-color: #fff!important;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值