vue实现el-table下采用递归实现自行添加子级,包括排序、编辑、删除

本文介绍了如何在项目开发中,特别是在后台管理系统中,通过递归实现表格元素的二级菜单功能,包括添加三级菜单、自增序号、父子级操作以及数据的分组、排序和树形结构构建。作者提供了具体的代码示例,展示了如何处理数据绑定和使用el-table组件实现这些功能。
摘要由CSDN通过智能技术生成

        在日常开发项目中,特别是有些后台管理系统,常用到项目流程中需要添加的子级(或者称为二级菜单),此场景可有效帮助你了解如何使用递归实现表格元素的二级。

需求: 用户可在项目应用点中,添加至三级菜单,其中序号实现自增并且实现对父级下的多层菜单实现编辑删除操作。(父级元素不可操作)

本人编写的这个项目因为需求,所以采用遍历后的item,源数据为tableData,所以el-table中的:data绑定为item,分类显示,若没有这个需求,则正常绑定后端传来的数据源即可,此处合并了数据,所以item便是等同于从后端请求过来的数据。大家可以根据自己的需求来编写html(此处不是重点!)

此处为实现分类编排列表的方法(非必要,大家按自身需求编写)

//按照计划阶段(planStage)进行分组
filterProgress(data) {
      const typeList = ['previous', 'desgin', 'build']
      const grouped = {
        previous: [],
        desgin: [],
        build: []
      }
      data.forEach((item) => {
        grouped[typeList[item.planStage - 1]]
          ? null
          : (grouped[typeList[item.planStage - 1]] = [])
        grouped[typeList[item.planStage - 1]].push(item)
      })
      return grouped
    },

接下来先编写排序方法,让表格中排序一列绑定的prop进行自增序号,定义setSort() 方法,用于给输入的数据 data 数组中的每个元素添加一个新的 newSort 属性,并根据传入的 count 参数为每个元素生成排序值。

具体来说,方法首先使用 map 方法遍历 data 数组中的每个元素,对每个元素进行处理:

  • 根据传入的 count 参数,生成一个新的排序值 newSort。如果 count 存在,则将 count 和当前元素在数组中的索引值(加一)拼接作为新的排序值;否则,直接使用当前元素在数组中的索引值(加一)作为排序值。
  • 如果当前元素具有 childList 属性且其长度大于 0,则递归调用 setSort 方法处理子元素,并将生成的排序值传递给子元素。

最后,方法返回一个新的数组 newArr,其中包含了对输入数组 data 中每个元素添加了新的 newSort 属性后的结果。定义的排序方法方便后续在buildTreeData()方法中调用

 setSort(data, count) {
      const newArr = data.map((item, index) => {
        const newSort = count ? count + '.' + (index + 1) : index + 1
        if (item.childList.length > 0) {
          item.childList = this.setSort(item.childList, newSort)
        }
        return {
          ...item,
          newSort: newSort
        }
      })
      return newArr
    },

 接着是编写buildTreeData()方法来实现构建树形数据结构,接受一个对象 obj 和一个可选的 level 参数作为输入。方法的作用是遍历对象 obj 中的每个键值对,对值进行处理,以构建树形结构的数据。具体来说,方法使用了一个 for...in 循环来遍历 obj 对象的属性。在循环中,首先判断当前属性值是否为数组,如果是数组,则遍历数组中的每个元素(通过 forEach 方法),对每个元素进行处理:

  • 将元素的 level 属性设置为当前传入的 level 值。
  • 如果元素有 childList 属性且其长度大于 0,则递归调用 buildTreeData 方法,传入一个包含 childList 的对象,并将 level 值加一,以处理子节点的数据。

接着,对每个键对应的值进行排序操作,使用 this.setSort 方法对数组进行排序,并将排序后的数组重新赋值给 obj[key]

最终,方法会对 obj 中的每个键值对进行处理,包括设置 level 属性和对数组进行排序,以构建完整的树形数据结构。

// 递归设置level
    buildTreeData(obj, level = 1) {
      for (const key in obj) {
        if (Array.isArray(obj[key])) {
          obj[key].forEach((item) => {
            item.level = level
            if (item.childList && item.childList.length > 0) {
              this.buildTreeData({ child: item.childList }, level + 1)
            }
          })
        }
        obj[key] = this.setSort(obj[key].sort((a, b) => a.sort - b.sort))
      }
    },

最后就是调用编写的方法,达到添加子级的效果

注:此处的list为请求数据的接口方法,大家可自行替换,user的处理大家也可以删除掉

init() {
      const { progressId } = this
      if (progressId === undefined) {
        this.$emit('toggleComponent', true)
      }
      const progerss = list(progressId)
      const user = getTeam(progressId)
      Promise.all([progerss, user]).then(([listResult, usersResult]) => {
        const data = listResult.entities
        this.tableData = this.filterProgress(data)
        this.buildTreeData(this.tableData)
        this.userList = usersResult.entities.filter((item, index, self) => {
          return self.findIndex((obj) => obj.userId === item.userId) === index
        })
      })
    },

文章到这里就结束了,大家如果觉得哪里写得不好可以留言哦!
共同学习,共同成长!

Vue3 中的 `el-table` 组件可以根据 `pid` 和上一级的 `id` 相同来进行递归合并单元格,这通常用于数据的分组展示,比如树形结构的数据。下面是一个简单的示例,使用 `v-for` 遍历嵌套的对象数组,并通过递归处理判断是否需要合并单元格: ```html <template> <el-table :data="treeData"> <el-table-column prop="name" label="名称"></el-table-column> <!-- 添加一个计算属性来合并单元格 --> <el-table-column v-if="isSameParent(row.pid, row.parentId)" show-overflow-tooltip render-cell="renderCell" ></el-table-column> </el-table> </template> <script> export default { data() { return { treeData: [ // 模拟树形数据,包含 pid 和 parentId 属性 { id: 1, name: 'A', pid: null, parentName: '', children: [] }, { id: 2, name: 'B', pid: 1, parentName: 'A', children: [{ id: 3, name: 'B1' }, { id: 4, name: 'B2' }] }, // ... 其他节点 ], }; }, methods: { isSameParent(pid, parentId) { return pid === parentId; }, renderCell(h, { row }) { if (row.children.length > 0) { return h('div', { style: 'white-space: nowrap; overflow: hidden; text-overflow: ellipsis;' }, row.name); // 这里可以使用递归,如果还有子级,继续渲染并合并 // 如果没有子级,渲染单行内容 } else { return row.name; } }, }, }; </script> ``` 在这个例子中,我们首先检查当前行的 `pid` 是否等于其父级的 `id`,如果是则会进入 `renderCell` 方法中的递归部分。当有子节点时,我们会合并显示所有子节点的名称,直到遇到没有子节点的节点为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值