先上个效果图
获取到的数据是这样的
[
{ 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是之前构建好的数据