携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
大家好,我是大帅子,今天给大家讲一下,我们后端返回的数据是一个平面结构的话,我们怎么转换为树形结构呢, 其实方法很多样, 今天就给大家讲一下其中的三种吧, 三种常用的,大家喜欢那个就用哪个吧~,嘿嘿,这么贴心的博主,还不都给小心心点起来~~~
介绍
我们先来看下面的数据吧
let arr = [
{ 'id': '29', 'pid': '', 'name': '总裁办' },
{ 'id': '2c', 'pid': '', 'name': '财务部' },
{ 'id': '2d', 'pid': '2c', 'name': '财务核算部' },
{ 'id': '2f', 'pid': '2c', 'name': '薪资管理部' },
{ 'id': 'd2', 'pid': '', 'name': '技术部' },
{ 'id': 'd3', 'pid': 'd2', 'name': 'Java研发部' }
]
- 这个是我们常从后端那,拿到的数据,我们观察一下数据
- 我们 的一级 的pid值是空值
- 我们的子级 的 pid值是父级的id值
OK 分析跟需求我就跟大家说到这里,这里,大家有什么思路吗 ? 可以尝试的写一下,然后回来再看一下我的方法,
1. 下包
没有什么是下包解决不了的,如果有的话,我们就 double , array-to-tree
步骤我带着大家可以看一下
- 下包
npm install array-to-tree --save
yarn add array-to-tree
- 里面有两种数据内容的数据 大家可以观察一下我们的数据更适合那种?
var dataOne = [
{
id: 1,
name: 'Portfolio',
parent_id: undefined
},
{
id: 2,
name: 'Web Development',
parent_id: 1
},
{
id: 3,
name: 'Recent Works',
parent_id: 2
},
{
id: 4,
name: 'About Me',
parent_id: undefined
}
];
var dataTwo = [
{
_id: 'ec654ec1-7f8f-11e3-ae96-b385f4bc450c',
name: 'Portfolio',
parent: null
},
{
_id: 'ec666030-7f8f-11e3-ae96-0123456789ab',
name: 'Web Development',
parent: 'ec654ec1-7f8f-11e3-ae96-b385f4bc450c'
},
{
_id: 'ec66fc70-7f8f-11e3-ae96-000000000000',
name: 'Recent Works',
parent: 'ec666030-7f8f-11e3-ae96-0123456789ab'
},
{
_id: '32a4fbed-676d-47f9-a321-cb2f267e2918',
name: 'About Me',
parent: null
}
];
- 这里很显然是第二种
- 那我们就跟着第二种方法走
// 1. 导包 import arrayToTree from 'array-to-tree' // 2. 可以定义一个工具函数 export function getTree(arr){ arrayToTree(arr, { parentProperty: 'pid', customID: 'id' }) } // 3. 使用 搞定 import {getTree} from '路径' getTree(arr)
2. 递归
这应该是我们第一时间该想到的, 是吧,因为我们的子组件可能会嵌套很多层, 所以我们就要用递归来搞
- 分析一下 我们可以什么都不用想 直接先定义一个函数
function getTree (){
}
- 这个时候我们就要想,其中我们数组形参肯定是必不可少,第二个形参我们应该传什么呢? 我们应该传
pid
先把第一层拿到,然后再去递归对吧,那么我们思路就清晰了
function getTree (arr,pid){
let newArr = []
arr.forEach(item=>{
if(item.pid === pid) {
newArr.push(item)
}
})
return newArr
}
-
ok 我们这个时候很顺利完成了第一步 , 我们的
newArr
里面就拿到了一级目录,但是我们此时是不是该想一下我们的参数第二个参数应该传什么呢?因为我们的 判断条件是 if(item.pid === pid) 所以我们的第二个形参是不是应该传一个空值 ,不要问为什么 ,我们可以不传,直接等于空,因为我们的递归第二层要用这个形参的位置
-
OK我们一个完成了一半,拿到了一级,我们是不是该,去拿第子级了,是吧? 所以我们开始吧,我们直接在函数的内部调用,此时我们在回顾一下我们的判断条件
if(item.pid === pid)
, 这个时候因为我们已经到了函数的内部里面,我们能拿到每一项, 所以我们只需要拿id
去跟pid
比较 ,这个时候,我们就可以筛选每个子级
function getTree (arr,pid){
let newArr = []
arr.forEach(item=>{
if(item.pid === pid) {
+ let child = getTree (arr,item.id)
newArr.push(item)
}
})
return newArr
}
- 收集起来 , 这个时候我们可以打印看一下,会有多空数组,然后我们需要过滤一下,拿到有数据的数组,然后添加到父级 , 这个就是递归的做法
function getTree (arr,pid){
let newArr = []
arr.forEach(item=>{
if(item.pid === pid) {
let child = getTree (arr,item.id)
+ if(child.length > 0){
+ item.children = child
+ }
newArr.push(item)
}
})
return newArr
}
getTree(list,'')
3. 来一个 层层解析,不用递归的
这就是一步一步的来, 我就不一步一步的带着大家走一遍了
export function tranTreeData(list) {
const obj = {}
// 这里我们拿到 每个对象的键就是 id ,值就是每一项
list.forEach(item => {
item.children = []
obj[item.id] = item
})
const newArr = []
list.forEach(item => {
if (obj[item.pid]) {
obj[item.pid].children.push(item)
} else {
newArr.push(item)
}
})
return newArr
}
好了,这边已经给大家介绍到这里,以上是我自己的理解,希望可以帮到大家, 欢迎留言我这边一定会第一时间给大家解答,喜欢的可以点赞收藏
🐣---->🦅 还需努力!大家一起进步!!!