一、list转tree的方法
我主要是用了两种方式:非递归和递归
首先定义一个数组,拿到我们需要的数据:
let arr = [
{
id: 1,
parentId: 0,
name: '市场部',
},
{
id: 2,
parentId: 0,
name: '运维部'
},
{
id: 3,
parentId: 0,
name: '开发部',
}
,
{
id: 4,
parentId: 1,
name: '线下推广部'
},
{
id: 5,
parentId: 1,
name: '网络推广部'
},
{
id: 6,
parentId: 3,
name: '大前端',
},
{
id: 8,
parentId: 6,
name: 'CRM系统开发',
}
, {
id: 7,
parentId: 3,
name: '后端部'
}
]
1.非递归
首先我们捋一下非递归方法的思路:遍历arr中每一个元素,找这个元素的父亲(v.id === pid)。
function listToTree(arr) {
let resArr = []
arr.forEach(v => {
// 找这个元素的 父亲(item.id === v.parentId)
// 去arr中 中 找v的父亲,找到的话,把v添加到父亲的children属性中
let parentNode = arr.find(item => item.id == v.parentId);
if (parentNode) {
// 如果没有找到父亲-说明 他是一级目录
if (parentNode['children']) {
//
parentNode['children'].push(v);
} else {
parentNode['children'] = [v];
}
} else {
//说明这个v 没有父亲
// v
resArr.push(v)
}
});
return resArr;
}
// console.log(listToTree(arr));
2.递归
递归的思想就是找儿子节点:遍历arr中的元素,看看元素的pid是否和id相等,如果相等就是它的孩子,添加到children中,第一个参数是id,第二个参数是存放孩子的数组,第三个参数是所有的元素数组。
function findChildren(id, children, arr) {
arr.forEach(v => {
if (v.parentId === id) {
children.push(v);
//v 有没有孩子
v.children = [];
//递归找v的孩子
findChildren(v.id, v.children, arr);
}
});
}
let r = []
findChildren(0, r, arr);
console.log(r);
二、tree转list的方法
也是分为了递归和非递归两种方法,很简单,就直接给大家看代码吧!
let brr = [
{
id: 1,
parentId: 0,
name: '市场部',
children: [
{
id: 4,
parentId: 1,
name: '线下推广部'
},
{
id: 5,
parentId: 1,
name: '网络推广部'
},
]
},
{
id: 2,
parentId: 0,
name: '运维部'
},
{
id: 3,
parentId: 0,
name: '开发部',
children: [
{
id: 6,
parentId: 3,
name: '大前端',
children: [
{
id: 8,
parentId: 6,
name: 'CRM系统开发',
}
]
},
,
, {
id: 7,
parentId: 3,
name: '后端部'
}
]
}
]
// 递归
function treeToList(tree, resArr) {
// 遍历tree -每一个元素,添加到resArr中
tree.forEach(v => {
// 把第一层元素 添加到resArr中
resArr.push(v);
// 判断是否有孩子,如果有孩子 ,添加到resArr中
if (v.children) {
treeToList(v.children, resArr)
}
});
}
let r = []
treeToList(brr, r)
console.log(r);
/**
*
非递归
queue = [,{id:4},{id:5},{}]
resArr {id:1} {id:2} {id:3},
*
*/
function treeToList(tree) {
// 定义空数组 -方法所有的tree中的元素
let resArr = []
// 定义了数组,放了tree里面的 第一层元素
let queue = [...tree]
// 循环--条件 queue 数组的长度不为0 就一直循环
while (queue.length) {
// 每次删除queue中第一个元素
let v = queue.shift()
// 如果可以取出来就把他添加到resArr
if (v) resArr.push(v);
// 判断v是否有孩子
if (v && v.children) {
queue.push(...v.children)
}
}
return resArr
}
console.log(treeToList(brr));
三、tree转ul,使用嵌套字符串渲染页面
html代码很简单,写一个容器就好了
<div id="box"></div>
js代码如下:
let brr = [
{
id: 1,
parentId: 0,
name: '市场部',
children: [
{
id: 4,
parentId: 1,
name: '线下推广部'
},
{
id: 5,
parentId: 1,
name: '网络推广部'
},
]
},
{
id: 2,
parentId: 0,
name: '运维部'
},
{
id: 3,
parentId: 0,
name: '开发部',
children: [
{
id: 6,
parentId: 3,
name: '大前端',
children: [
{
id: 8,
parentId: 6,
name: 'CRM系统开发',
}
]
},
,
, {
id: 7,
parentId: 3,
name: '后端部'
}
]
}
];
//tree 转为 ul
function treeToUl(tree) {
// 遍历tree 数组-元素--拼接成多个 li字符串
let liStr = '';
tree.forEach(obj => {
//判断obj 是有有children -》 如果有 children 转为ul
let secondUl = ''
if (obj.children) {
secondUl = treeToUl(obj.children);
}
liStr += `<li>${obj.name} ${secondUl}</li>`
});
let ulStr = `<ul>${liStr} </ul>`;
return ulStr;
}
// console.log();
document.querySelector('div').innerHTML = treeToUl(brr)
对于tree和list之间的两种状态转换,我们先捋清思路再练习,多敲敲熟悉代码。