前端必备!掌握树形结构的处理方式!

63 阅读2分钟

一、前言

前端工程师不管是使用Vue还是React框架,都离不开路由。对于单页面应用,一个路由对应一个页面。做后台系统就离不开对路由的处理,通过权限筛选出对应的路由。那么,当数据结构的形式为如下图所示,该如何处理呢?下文将使用两种常见的方式进行处理。

const data = [ 
    { id:1, pid:0, name:'Course', title:'课程管理', path:'/course' }, 
    { id:2, pid:1, name:'CourseOperate', title:'课程操作', path:'operate', link:'/course/operate' }, 
    { id:3, pid:2, name:'CourseInfoData', title:'课程数据', link:'/course/operate/info_data', path:'info_data' },
    { id:4, pid:0, name:'Class', title:'班级管理', path:'/class' }, 
    { id:5, pid:4, name:'AddClass', title:'增加班级', path:'addClass', link:'/class/addClass' } 
]

二、处理方式

(1)递归处理

  1. 首先把这个数组的拆分为父级(pid为0)列表和子级(pid不为0)列表。
  2. 遍历每个父级列表,同时遍历子级列表,当子项pid等于父级id,说明找到一个子项是当前父级的。
  3. 深拷贝一份子级列表,因为已经找到一个子项了,可以直接在这个副本删除,避免重复查找,然后继续递归。
  4. 判断当前父级是否有children,有的话直接将子项push进去,否则创建children

代码如下:

const treeData = formatTreeData(data) 

const formatTreeData = (data) => { 
    // 获取父级 
    const parent = data.filter(item => item.pid === 0) 
    // 获取子级 
    const children = data.filter(item => item.pid !== 0) 
    dataToTree(parent,children) 
    return parent 
} 

const dataToTree = (parent,children) => { 
    parent.map(p => { 
        children.map((c,i) => {
            // 当子级pid等于父级id时进行操作
            if(p.id === c.pid){
                 // 深拷贝子级数组 
                let _children = JSON.parse(JSON.stringify(children)) 
                // 删除当前项
                _children.splice(i,1) 
                // 继续递归遍历子级 
                dataToTree([c],_children) 
                // 当前父级是否有children,有的话直接push,否则创建children 
                if(p.children){ 
                    p.children.push(c) 
                }else{ 
                    p.children = [c] 
                } 
            } 
        }) 
    }) 
}

(2)扁平化处理

扁平化处理就是初始时把每一项都当做父级,在遍历每一项的同时,收集当前项的子级。代码如下:

const formatTreeData = (data) => { 
    let _data = JSON.parse(JSON.stringify(data)) 
    // 遍历每一项的同时,收集当前项的子集 
    return _data.filter(p => { 
        const _arr = _data.filter(c => c.pid === p.id) _arr.length && (p.children = _arr) 
        return p.pid === 0 
    }) 
}

三、测试结果

image.png

欢迎关注公众号---代码分享站

v2-88d54674ec29c2990c2ee8c4fb228163_b.jpg