导航
[
{ id: 1, pid: -1, name: "一级菜单A", rank: 1 },
{ id: 2, pid: -1, name: "一级菜单B", rank: 1 },
{ id: 3, pid: -1, name: "一级菜单C", rank: 1 },
{ id: 4, pid: 1, name: "二级菜单A-A", rank: 2 },
{ id: 5, pid: 1, name: "二级菜单A-B", rank: 2 },
{ id: 6, pid: 2, name: "二级菜单B-A", rank: 2 },
{ id: 7, pid: 4, name: "三级菜单A-A-A", rank: 3 },
{ id: 8, pid: 7, name: "四级菜单A-A-A-A", rank: 4 },
{ id: 9, pid: 8, name: "五级菜单A-A-A-A-A", rank: 5 },
{ id: 10, pid: 9, name: "六级菜单A-A-A-A-A-A", rank: 6 },
{ id: 11, pid: 10, name: "七级菜单A-A-A-A-A-A-A", rank: 7 },
{ id: 12, pid: 11, name: "八级菜单A-A-A-A-A-A-A-A", rank: 8 },
{ id: 13, pid: 12, name: "九级菜单A-A-A-A-A-A-A-A-A", rank: 9 },
{ id: 14, pid: 13, name: "十级菜单A-A-A-A-A-A-A-A-A-A", rank: 10 },
]
思路:找儿子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>树形结构</title>
</head>
<body>
<script>
let data = [
{ id: 1, pid: -1, name: "一级菜单A", rank: 1 },
{ id: 2, pid: -1, name: "一级菜单B", rank: 1 },
{ id: 3, pid: -1, name: "一级菜单C", rank: 1 },
{ id: 4, pid: 1, name: "二级菜单A-A", rank: 2 },
{ id: 5, pid: 1, name: "二级菜单A-B", rank: 2 },
{ id: 6, pid: 2, name: "二级菜单B-A", rank: 2 },
{ id: 7, pid: 4, name: "三级菜单A-A-A", rank: 3 },
{ id: 8, pid: 7, name: "四级菜单A-A-A-A", rank: 4 },
{ id: 9, pid: 8, name: "五级菜单A-A-A-A-A", rank: 5 },
{ id: 10, pid: 9, name: "六级菜单A-A-A-A-A-A", rank: 6 },
{ id: 11, pid: 10, name: "七级菜单A-A-A-A-A-A-A", rank: 7 },
{ id: 12, pid: 11, name: "八级菜单A-A-A-A-A-A-A-A", rank: 8 },
{ id: 13, pid: 12, name: "九级菜单A-A-A-A-A-A-A-A-A", rank: 9 },
{ id: 14, pid: 13, name: "十级菜单A-A-A-A-A-A-A-A-A-A", rank: 10 },
];
function formatData(data) {
let parents = [], children = [];
// 先把第一层 父亲们 和 儿子们 分开来(pid = -1的都是父亲)
data.forEach(item => {
item.pid === -1
? parents.push(item)
: children.push(item);
});
// 调用递归函数
dataToTree(parents, children);
// 最终返回 树结构
return parents;
// 接收两个参数,一个是 父亲们,一个是 儿子们
function dataToTree(parents, children) {
parents.forEach(p => {
children.forEach((c, i) => {
// 当儿子找到了父亲
if (c.pid === p.id) {
// 拷贝一下所有儿子
const _children = JSON.parse(JSON.stringify(children));
// 从儿子中剔除当前已经找到父亲的儿子
_children.splice(i, 1);
// 去找当前的 儿子,还有没有自己的儿子
dataToTree([c], _children);
// 把儿子放到父亲那儿去
if (p.children) {
p.children.push(c);
} else {
p.children = [c];
}
}
});
});
}
}
const tree = formatData(data);
console.log(tree);
</script>
</body>
</html>
思路:找父亲
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>树形结构</title>
</head>
<body>
<script>
let data = [
{ id: 1, pid: -1, name: "一级菜单A", rank: 1 },
{ id: 2, pid: -1, name: "一级菜单B", rank: 1 },
{ id: 3, pid: -1, name: "一级菜单C", rank: 1 },
{ id: 4, pid: 1, name: "二级菜单A-A", rank: 2 },
{ id: 5, pid: 1, name: "二级菜单A-B", rank: 2 },
{ id: 6, pid: 2, name: "二级菜单B-A", rank: 2 },
{ id: 7, pid: 4, name: "三级菜单A-A-A", rank: 3 },
{ id: 8, pid: 7, name: "四级菜单A-A-A-A", rank: 4 },
{ id: 9, pid: 8, name: "五级菜单A-A-A-A-A", rank: 5 },
{ id: 10, pid: 9, name: "六级菜单A-A-A-A-A-A", rank: 6 },
{ id: 11, pid: 10, name: "七级菜单A-A-A-A-A-A-A", rank: 7 },
{ id: 12, pid: 11, name: "八级菜单A-A-A-A-A-A-A-A", rank: 8 },
{ id: 13, pid: 12, name: "九级菜单A-A-A-A-A-A-A-A-A", rank: 9 },
{ id: 14, pid: 13, name: "十级菜单A-A-A-A-A-A-A-A-A-A", rank: 10 },
];
function formatData2(data) {
let _data = JSON.parse(JSON.stringify(data));
return _data.filter(p => {
// 遍历每个对象,找自己的儿子们
let _arr = _data.filter(c => c.pid === p.id);
_arr.length && (p.children = _arr);
return p.pid === -1;
});
}
const tree = formatData2(data);
console.log(tree);
</script>
<script>
// 或者找自己的父亲
function formatData(arr) {
return arr.filter((v) => {
if (v.pid === -1) {
return v;
} else {
const parent = arr.find((c) => c.id === v.pid);
if (parent.children) {
parent.children.push(v);
} else {
parent.children = [v];
}
}
});
}
</script>
</body>
</html>