一、前言
前端工程师不管是使用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)递归处理
- 首先把这个数组的拆分为父级(pid为0)列表和子级(pid不为0)列表。
- 遍历每个父级列表,同时遍历子级列表,当子项pid等于父级id,说明找到一个子项是当前父级的。
- 深拷贝一份子级列表,因为已经找到一个子项了,可以直接在这个副本删除,避免重复查找,然后继续递归。
- 判断当前父级是否有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
})
}
三、测试结果
欢迎关注公众号---代码分享站