【通俗易懂】vue-elementul实现树形数据表格,后台返回的扁平化数组进行树形结构转换处理

效果图

需求是做一个这种的多层级表格,树形数据表格。
在这里插入图片描述

大家可能遇到的问题

一种是不知道如何做这种多层级的表格
一种是后台给自己返回的数据不是树形的,也就是没有子父级。全是一条条的扁平化数组。类似这样
在这里插入图片描述
而我们需要的结构是这样
在这里插入图片描述
那么问题就来了,我们如何把这一段数据给处理转换成树形结构呢。

我在网上看了好多的帖子学习,发现很多都是写的很复杂或者只写了一部分,那我就来弄一个全覆盖的额好了,从如何做表,到万一给你的是扁平数组如何转换成树行的。一次搞定

扁平数组转换树形结构方法

这个也是网上看到一个算法大佬的写法,经过测试,确实有效,而且特别简便。

    setTreeData(source){
    
    
    let cloneData = JSON.parse(JSON.stringify(source))      // 对源数据深度克隆
    return  cloneData.filter(father=>{
    
                          // 循环所有项,并添加children属性
        let branchArr = cloneData.filter(child=> father.menuId == child.parentId);   // 返回每一项的子级数组
        branchArr.length>0 ? father.children=branchArr : ''   //给父级添加一个children属性,并赋值
        return father.parentId==0;      //返回第一层
    });

解释一下用法:

1,你需要发请求获取后台给你的数组,然后在你的.then()内调用这个setTreeData方法,并把你们的数组传参过去,比如这样this.setTreeData(data),这个data就是你请求拿到的数据。
2,你需要看一下这里面的father.menuId这句话,他对应的是id,因为我的项目后台返回的id他取名是menuId所以我改成了menuid,你们要看下自己的数据里是id还是什么其他名字,修改一下就能用了,后面的parentId我看了很多人的数据,基本都是一样的名字,没有人动这个的,如果不一样,那也需要改一下。

解释一下逻辑:

很简单的逻辑,首先把拿到的数据克隆一份存到cloneData变量内,然后循环这个变量,两个filter循环的逻辑是把第一项的id和所有项的parentId做比较,parentId代表上级菜单,一般这个上级菜单写的就是上级菜单的id一样的,所以我们比较一下,如果是一致的,那就代表这个是第一项的子级,那就返回这一项到branchArr内。一直循环比较完毕后,接下继续循环第二项,还是一样第二项的id和所有项的parentId比较找一样的给到branchArr内,然后第三项,第四项以此类推把所有id都比较一遍后就找到了所有id对应的子级,这时候判断branchArr长度大于0吗,如果大于代表有子级,那就创建一个childern字段,值就是branchArr的数据。最后把parentId==0的返回,等于0代表没有上级菜单,那他就是最顶级的菜单,所以他返回了就是第一层的菜单。

好啦,到这里大家应该懂了这个树形转换的逻辑了吧。那我们开始说如何把表格做出来。
这就需要用到我们的elementul组件了,非常方便。

树形数据表格

<template>
<div>
  <el-table
    :data="tableData"
    style="width: 100%;margin-bottom: 20px;"
    row-key="id"
    border
    default-expand-all
    :indent="20"
    :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
    <el-table-column
      prop="date"
      label="日期"
      sortable
      width="180">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      sortable
      width="180">
    </el-table-column>
    <el-table-column
      prop="address"
      label="地址">
    </el-table-column>
  </el-table>
</div>
</template>
<script>
  export default {
    
    
    data() {
    
    
      return {
    
    
        tableData: [ {
    
    
          id: 3,
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄',
          children: [{
    
    
              id: 31,
              date: '2016-05-01',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄'
            }, {
    
    
              id: 32,
              date: '2016-05-01',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄',
              children: [{
    
    
              id: 34,
              date: '2016-05-01',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄'
            }, {
    
    
              id: 35,
              date: '2016-05-01',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄'
          }]
          }]
        }, {
    
    
          id: 4,
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }],
      }
    },
    methods: {
    
    
      load(tree, treeNode, resolve) {
    
    
        setTimeout(() => {
    
    
          resolve([
            {
    
    
              id: 31,
              date: '2016-05-01',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄'
            }, {
    
    
              id: 32,
              date: '2016-05-01',
              name: '王小虎',
              address: '上海市普陀区金沙江路 1519 弄'
            }
          ])
        }, 1000)
      }
    },
  }
</script>

解释一下写法:

这其时就是elementul官网上复制的一段代码,table表格组件有一个树形数据与懒加载的表格可以参考。
重点说一下注意点。
写在el-table标签上的属性意思解释:

两个必须要写的,row-key="id"这个id对应你的数据的id或者像我一样的menuId。反正别重复,是一个标记区分的作用。tree-props的意思是,再你的数据内如果哪一条有children字段就展开,里面放子级,刚好我们刚才数据已经转换了,现在里面有children字段了可以用来判断,这个地方注意的是children: 'children’这个前面不能改,后面的名字可以改,根据你数据里面的子级字段改,比如我们正常人的子级都是用children表示,如果你们公司的后端比较叛逆偏偏要用ABC来表示,那就是children: 'ABC’懂吧。
至于后面的hasChildren: 'hasChildren’基本用不到。

row-key="id"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"

这个indent意思就是你表格展开后的偏移量,每一级首行缩进多少。也是加在el-table上的属性

:indent="20"

还可以在el-table上加一个lazy属性,代表了子级懒加载。

如果你想要单独弄一行来放小箭头用于展开表格那你就再最前面加一个el-table-column就可以,默认第一个el-table-column放箭头

如果你想要控制箭头的位置不放在第一个el-table-column怎么做呢,很简单,给他家type属性,加了type的el-table-column小箭头就不会去会往后找没有type 的,所以你只需要把前面的都加上type在你需要的那一个el-table-column上不加type就可以控制箭头在哪里了。

猜你喜欢

转载自blog.csdn.net/seeeeeeeeeee/article/details/119458019