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
}

逻辑很简单,就这?费了我一个多小时的时间,浪费了我几亿个脑细胞。

逻辑如下:

  1. 给所有的项添加一个children属性
  2. 获取到一级项放到一个数组
  3. 遍历所有不是一级菜单的项,如果子菜单的parentID等于父级的id了,push进父级的children数组中,在判断当前的item是不是也有children,有的话直接将当前item当做父级进行递归。

演示一下效果吧:

上一篇下一篇

猜你喜欢

热点阅读