js構造樹形菜單


先上個效果圖

獲取到的數據是這樣的

[
    { id: 1, text: '一級菜單A', parentId: null },
    { id: 2, text: '一級菜單B', parentId: null },
    { id: 3, text: '一級菜單C', parentId: null },
    { id: 4, text: '二級菜單AA', parentId: 1 },
    { id: 5, text: '二級菜單AB', parentId: 1 },
    { id: 6, text: '二級菜單AC', parentId: 1 },
    { id: 7, text: '二級菜單BA', parentId: 2 },
    { id: 8, text: '二級菜單BB', parentId: 2 },
    { id: 9, text: '二級菜單BC', parentId: 2 },
    { id: 10, text: '二級菜單CA', parentId: 3 },
    { id: 11, text: '二級菜單CB', parentId: 3 },
    { id: 12, text: '二級菜單CC', parentId: 3 },
    { id: 13, text: '三級菜單AAA', parentId: 4 },
    { id: 14, text: '三級菜單BAA', parentId: 7 },
    { id: 15, text: '三級菜單CAA', parentId: 10 }
    ]

那如何將這些數據轉化為樹狀結構並渲染出來

先上完整代碼

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        ul,
        li {
            list-style: none;
        }
    </style>
</head>

<body>
    <div class="nav">

    </div>
</body>
<script>
    // 數據
    let navData = [
    { id: 1, text: '一級菜單A', parentId: null },
    { id: 2, text: '一級菜單B', parentId: null },
    { id: 3, text: '一級菜單C', parentId: null },
    { id: 4, text: '二級菜單AA', parentId: 1 },
    { id: 5, text: '二級菜單AB', parentId: 1 },
    { id: 6, text: '二級菜單AC', parentId: 1 },
    { id: 7, text: '二級菜單BA', parentId: 2 },
    { id: 8, text: '二級菜單BB', parentId: 2 },
    { id: 9, text: '二級菜單BC', parentId: 2 },
    { id: 10, text: '二級菜單CA', parentId: 3 },
    { id: 11, text: '二級菜單CB', parentId: 3 },
    { id: 12, text: '二級菜單CC', parentId: 3 },
    { id: 13, text: '三級菜單AAA', parentId: 4 },
    { id: 14, text: '三級菜單BAA', parentId: 7 },
    { id: 15, text: '三級菜單CAA', parentId: 10 }
    ];
    // let nav = document.getElementsByClassName('nav')
    let nav = document.querySelector('.nav')
    // 將數組置為樹形
    let treeee = (function makeTreeData(arr, parentId) {
        let temp = []
        for (let i = 0; i < arr.length; i++) {
            if (arr[i].parentId === parentId) {
                temp.push(arr[i])
                arr[i].children = makeTreeData(navData, arr[i].id)
            }
        }
        return temp
    })(navData, null)
    console.log(treeee);
    // 創造dom樹
    (function makeDomTree(data, node) {
        let ul
        for (let i = 0; i < data.length; i++) {
            ul = document.createElement('ul')
            let li = document.createElement('li')
            li.innerHTML = data[i].text
            node.appendChild(ul)
            ul.appendChild(li)
            if (data[i].children.length !== 0) {
                let element = makeDomTree(data[i].children, ul)
                ul.appendChild(element)
            }

        }
        return ul
    })(treeee, nav)
</script>

</html>

分為兩步

解析

第一步將數據進行轉化

需要將數據轉化為如下格式

      [
          { id: 1,
            text: '一級菜單A', 
            parentId: null ,
            children:[
                  { id: 4, text: '二級菜單AA', parentId: 1 ,children[{ id: 13, text: '三級菜單AAA', parentId: 4,children:[] }]},
                  { id: 5, text: '二級菜單AB', parentId: 1 ,children[]},
                  { id: 6, text: '二級菜單AC', parentId: 1 ,children[]}
            ]
            },
      ...
      ]

也就是說可以利用children屬性讓我們很清楚的看到,每個菜單的子菜單有多少項並包含着每項子菜單的每個屬性
代碼時這樣子的,利用遞歸算法直接構建數據

 let treeee = (function makeTreeData(arr, parentId) {
        let temp = []
        for (let i = 0; i < arr.length; i++) {
            if (arr[i].parentId === parentId) {
                temp.push(arr[i])
                arr[i].children = makeTreeData(navData, arr[i].id)
            }
        }
        return temp
    })(navData, null)
    console.log(treeee);

第二步將數據渲染至頁面

let nav = document.querySelector('.nav')
(function makeDomTree(data, node) {
        let ul //創建一個ul節點
        for (let i = 0; i < data.length; i++) {
            ul = document.createElement('ul')
            let li = document.createElement('li')
            li.innerHTML = data[i].text
            node.appendChild(ul)
            ul.appendChild(li)
            //以上幾步是將當前數組的每個項都作為一個li放置到ul中
            //若有子項進行遞歸操作
            if (data[i].children.length !== 0) {
                let element = makeDomTree(data[i].children, ul)
                ul.appendChild(element)
            }

        }
        return ul //返回ul節點
    })(treeee, nav) //treeee是之前構建好的數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM