在前端的开发过程中,我们有时候会碰到这么种情况,后端给我们的是一组平铺的数据。
而我们需要渲染的却是一个树形结构图,那么我们要怎么将其进行转化呢?
[
{id:"01", pid:"", "name":"老王" },
{id:"02", pid:"01", "name":"小张" },
{id:"03", pid:"01", "name":"老王" },
{id:"04", pid:"", "name":"老李" },
{id:"05", pid:"04", "name":"小黄" },
{id:"06", pid:"04", "name":"小丽" }
]
从上面的id
和pid
我们可以大致看出来上下级关系,但是数据是一个平铺的数据,并不利于我们进行渲染
这时我们可以封装一个工具,对这个数据进行转化,将其转化成树形结构
一、递归法
递归的方法相对来说比较方便,但对于一部分程序员而言可能不是特别的好理解,下面我拆分进行讲解一下
首先我们先声明一个函数,然后往里面传入两个值
list // 第一个是你需要进行转化的数组
pid // 第二个是你需要转化的数据里面的一级数据的值 我们这里pid:''代表的顶级
函数传参使用pid = ''
代表你调用函数不进行传值时,这个''
就是你的默认值,可以自行进行修改
然后我们先将所有pid=""
的数据筛选出来
function toRee (list,pid = '' ){
let newList = list.filter(it =>it.pid === pid)
return newList
}
做到这一步,我们得到了有两个pid=''
对象的数组
然后我们对这个数组进行遍历(只要是能循环数组,并且返回这个值的都可以,比如map()等方法都可以),给这两个对象添加一个children
属性
并将他的值等于调用的函数的返回值
function toRee (list,pid = '' ){
let newList= list.filter(it =>it.pid === pid)
newList.forEach(it => it.children = toRee(list,it.id) )
return newList
}
这个返回值是关键.他是一个数组,并且是一个pid等于newList里面每一个对象id的值
这样就形成了一个递归,直到没有newList不再是数组就开始进行返回
相对于下面的非递归相比,越是层级深的数据使用递归函数,他的循环次数会越多
二、非递归法
这里我写的是一种非递归法进行的数据转化
function totree(arr) {
const newArr = []
const map = {}
先进行变量的声明
arr.forEach(item => {
if(!item.children) item.children = []; 判断数据是否有子级 没有则进行子级的添加
map[item.id] = item // 添加对应的映射关系
})
再通过循环 判断每一个数据是否有子级 没有就添加子级属性,值是一个空数组
重点 这里进行了数据的映射
将所有的数据的id去出来,然后采用键值对的形式生成一个新的对象,方便我们后面进行比对
{
01: {id:"01", pid:"", "name":"老王" },
02: {id:"02", pid:"01", "name":"小张" },
03: {id:"03", pid:"01", "name":"老王" },
04: {id:"04", pid:"", "name":"老李" },
05: {id:"05", pid:"04", "name":"小黄" },
06: {id:"06", pid:"05", "name":"小丽" }
}
最后再进行一次循环,将所有有pid值的数据添加到跟pid对应的id映射的对象的子级里面
arr.forEach(item => {
if (map[item.pid]) {
map[item.pid].children.push(item)
} else {
newArr.push(item)
}
})
return newArr
}
export default totree
这样就完成了所有的操作,将newArr
进行return就行
判断上下级的数据不同的话,修改里面的对应数据即可
完整代码如下
function totree(arr) {
const newArr = []
const map = {}
arr.forEach(item => {
if(!item.children) item.children = []; 判断数据是否有子级 没有则进行子级的添加
map[item.id] = item // 添加对应的映射关系
})
arr.forEach(item => {
if (map[item.pid]) {
map[item.pid].children.push(item)
} else {
newArr.push(item)
}
})
return newArr
}
export default totree
最后欢迎大家点赞