今天在項目中遇到了一個問題,我想要在el-table中使用樹形數(shù)據(jù),奈何該屬性數(shù)據(jù)需要一個children子節(jié)點,而后端只給我返回了平級數(shù)據(jù),每條數(shù)據(jù)中,有一個parentID字段,代表父級的id,0代表是一級菜單
以下為模擬的平級數(shù)據(jù):
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 },
]
我需要將此數(shù)據(jù)轉(zhuǎn)化為能使用的樹狀數(shù)據(jù)形式
以下為樹狀數(shù)據(jù)格式:
[
{
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. 先將一級菜單獲取到,放到一個數(shù)組里邊
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節(jié)點 把當前的item項當做父節(jié)點進行遞歸
// console.log(item, "子節(jié)點中仍然存在children節(jié)點")
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
}
邏輯很簡單,就這?費了我一個多小時的時間,浪費了我?guī)變|個腦細胞。
邏輯如下:
- 給所有的項添加一個children屬性
- 獲取到一級項放到一個數(shù)組
- 遍歷所有不是一級菜單的項,如果子菜單的parentID等于父級的id了,push進父級的children數(shù)組中,在判斷當前的item是不是也有children,有的話直接將當前item當做父級進行遞歸。
演示一下效果吧:
