js如何将多级菜单平级数据转化为树状数据?
2021-06-08 本文已影响0人
辰漪
今天在项目中遇到了一个问题,我想要在el-table中使用树形数据,奈何该属性数据需要一个children子节点,而后端只给我返回了平级数据,每条数据中,有一个parentID字段,代表父级的id,0代表是一级菜单
以下为模拟的平级数据:
const arr = [
{ id: 1, name: "张三", age: 18, parentID: 0 },
{ id: 2, name: "李四", age: 18, parentID: 0 },
{ id: 3, name: "王五", age: 18, parentID: 0 },
{ id: 4, name: "张三丰", age: 18, parentID: 1 },
{ id: 5, name: "李思夜", age: 18, parentID: 2 },
{ id: 6, name: "李思思", age: 18, parentID: 5 },
{ id: 7, name: "张三爷", age: 18, parentID: 4 },
{ id: 8, name: "张大爷", age: 18, parentID: 7 },
{ id: 9, name: "去你大爷", age: 18, parentID: 8 },
]
我需要将此数据转化为能使用的树状数据形式
以下为树状数据格式:
[
{
id: 1,
name: "张三",
age: 18,
parentID: 0,
children: [
{
id: 4,
name: "张三丰",
age: 18,
parentID: 1,
children: [{ id: 7, name: "张三爷", age: 18, parentID: 4 }],
},
],
},
]
就此我开始了费尽脑汁的写出了这么一段js逻辑代码...
直接上代码:
function getList(arr) {
let newArr = []
addField(arr) // 给所有的分类添加上一个children字段
const lv1 = getLv1(arr) // 1. 先将一级菜单获取到,放到一个数组里边
newArr = addSon(lv1)
function addSon(lv1) {
arr.forEach((item) => {
if (item.parentID !== 0) {
lv1.forEach((lv1Item) => {
if (item.parentID === lv1Item.id) {
lv1Item.children.push(item)
if (item.children) {
//如果该item 还存在children节点 把当前的item项当做父节点进行递归
// console.log(item, "子节点中仍然存在children节点")
const newarr = []
newarr.push(item)
return addSon(newarr)
}
}
})
}
})
return lv1
}
// 获得一级菜单 并且给每一个item附上children
function getLv1(arr) {
const lv1 = []
arr.forEach((item) => {
if (item.parentID === 0) {
lv1.push(item)
}
})
return lv1
// 添加children字段
function addField(arr) {
arr.forEach((item) => {
item.children = []
})
}
return newArr
}
逻辑很简单,就这?费了我一个多小时的时间,浪费了我几亿个脑细胞。
逻辑如下:
- 给所有的项添加一个children属性
- 获取到一级项放到一个数组
- 遍历所有不是一级菜单的项,如果子菜单的parentID等于父级的id了,push进父级的children数组中,在判断当前的item是不是也有children,有的话直接将当前item当做父级进行递归。
演示一下效果吧: