嵌套表格的选择表头功能实现

抛出问题

这次要给表格添加选择表头功能,用户自己设置哪些表头要展示,哪些要隐藏。本身功能比较简单,不过因上一篇嵌套表头已经实现了,所以这次的选择表头也要相应处理。

以下代码为vue3,如果开发依赖于vue2的话,更改部分语法即可,大体代码都一致(因部分代码是从我自己项目拷过来的,所以删了很多与当前功能无关的代码,不过应该也能正常运行,如果复制到自己项目不能运行的话可留言)

先来看效果:

效果图

这里我的实现方式是:不管有没有嵌套情况,让用户操作的表头总是最后一级的表头

解决思路

无嵌套:表头行是依据传入的columns数组决定的,现在可以默认给数组中每个对象增加hidden 属性代表是否需要隐藏。默认都不需要,等用户操作当前页表格的时候把对应的项hidden 设置为true即可

对于表头嵌套的情况:其实也是给最后一级的项设置hidden ,这里有个问题是怎样找到这一项然后给他设置hidden 属性。比如我把基本情况->是否成年->成年这一项隐藏的话,总不能从开头一直循环循环循环循环来查找。这里我用的方法是获取到columns之后,把每一个最后一级项展开,然后操作完隐藏某些表头项之后再还原。展开的过程中在每一个最后一级的属性中标注它的父label是什么,祖父label是什么等等,方便后面追根溯源

例如:

传入的column为

const compTableOpts = reactive({
      key: 'id',
      columns: [
        { label: 'ID', value: 'id' },
        { label: '姓名', value: 'name' },
        { label: '爱好', value: 'hobby', headerSlot: 'header3' },
        {
          label: '基本情况',
          children: [
            { label: '性别', value: 'sex' },
            { label: '年龄', value: 'age' },
            {
              label: '是否成年',
              children: [
                { headerSlot: 'header1', value: 'adult', label: '成年' },
                { headerSlot: 'header2', value: 'minor', slotFlag: true, label: '未成年' }
              ]
            }
          ]
        }
      ]
    })

经过展开处理之后为:

展开之后

对未成年这个表头进行隐藏处理之后:

restore

实现方法

这里我把展开还原数组操作抽取出来,里面每个方法有大概的解释

import { ref } from 'vue'

export default function useFlatAndRestore() {
  const flatArr = ref([])
  let changeThIndex = 0

  // 对columns进行展开处理,changeThIndex其实是parent几,columns每一项如果有父级的话都是从parent1开始
  function flatColumns(columns) {
    columns.forEach(item => {
      changeThIndex = 0
      flatChildren(item)
    })
  }

  // 判断当前项是否有children,有的话给他的子级都加上parent几:当前项的label这个属性。对数组展开之后的结果保存在flatArr中
  function flatChildren(item, parent) {
    if (parent) {
      item[`parent${changeThIndex}`] = parent.label
      Object.keys(parent).forEach(k => {
        if (k.indexOf('parent') !== -1) item[k] = parent[k]
      })
    }

    if (item.children) {
      changeThIndex = changeThIndex + 1
      item.children.forEach(t => {
        flatChildren(t, item)
      })
      changeThIndex = changeThIndex - 1
      return
    }
    flatArr.value.push(item)
  }

   // 重置flatArr
  function resetFlatArr() {
    flatArr.value = []
  }

  const restoreArr = ref([])
  // 对展开的数组进行还原操作,如果当前项没有以parent开头的属性,代表它没有父级。最终结果保存在restoreArr中
  function restoreColumns(newList) {
    newList.forEach(item => {
      const keys = Object.keys(item)
      if (keys.every(t => t.indexOf('parent') === -1)) {
        restoreArr.value.push(item)
        return
      }
      restoreParent(restoreArr.value, item)
    })
  }

  let i = 0
  let temData = {}
  // 判断要在数组的哪一项中的children进行push操作,比如:某一项的parent1为'基本情况',则要在'基本情况'的children中push这一项,以此类推
  function restoreParent(arr, item) {
    i = i + 1
    let flag
    arr.forEach(t => {
      if (t.label === item[`parent${i}`]) {
        flag = true
        temData = t
      }
    })
    if (!item[`parent${i}`]) {
      arr.push(item)
      return
    }
    if (!flag) {
      const obj = {
        label: item[`parent${i}`],
        children: []
      }
      restoreParent(obj.children, item)
      arr.push(obj)
    } else {
      restoreParent(temData.children, item)
    }
    i = 0
    temData = {}
  }

  // 重置restoreArr
  function resetRestoreArr() {
    restoreArr.value = []
  }

  return {
    flatColumns,
    flatArr,
    restoreColumns,
    restoreArr,
    resetRestoreArr,
    resetFlatArr
  }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值