推荐大家使用这位大佬(蔚莱先森)的转化方式(5行代码,很精简)
蔚莱先森:https://blog.youkuaiyun.com/Mr_JavaScript/article/details/82817177
本人转换代码大概20行,使用双层for循环,而大佬使用filter方式,结果一致,自己有需要可以再改造
场景
后台传来的菜单数据是没有层级的,只有parentId标识,像vue中的tree table数据接收都需要有父子层级关系的数据格式,所以需要前端人员进行格式转换成有childre[ ]父子级格式的数据(那么问题来了,为什么不让后端转换好发送给前端人员呢?答案是:我是后端人员o( ̄︶ ̄)o,哈哈)
上代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
aaaaaaaaa
<script>
let source = [
{id:1,parentId:0,name:"一级菜单A",rank:1},
{id:2,parentId:0,name:"一级菜单B",rank:1},
{id:3,parentId:0,name:"一级菜单C",rank:1},
{id:4,parentId:1,name:"二级菜单A-A",rank:2},
{id:5,parentId:1,name:"二级菜单A-B",rank:2},
{id:6,parentId:2,name:"二级菜单B-A",rank:2},
{id:7,parentId:4,name:"三级菜单A-A-A",rank:3},
{id:8,parentId:7,name:"四级菜单A-A-A-A",rank:4},
{id:9,parentId:8,name:"五级菜单A-A-A-A-A",rank:5},
{id:10,parentId:9,name:"六级菜单A-A-A-A-A-A",rank:6},
{id:11,parentId:10,name:"七级菜单A-A-A-A-A-A-A",rank:7},
{id:12,parentId:11,name:"八级菜单A-A-A-A-A-A-A-A",rank:8},
{id:13,parentId:12,name:"九级菜单A-A-A-A-A-A-A-A-A",rank:9},
{id:14,parentId:13,name:"十级菜单A-A-A-A-A-A-A-A-A-A",rank:10}
];
console.log(source)
//第一种: filter 方式
function setTreeData(source){
let cloneData = JSON.parse(JSON.stringify(source)) // 对源数据深度克隆
return cloneData.filter(father=>{ // 循环所有项,并添加children属性
let branchArr = cloneData.filter(child=>father.id == child.parentId); // 返回每一项的子级数组
branchArr.length>0 ? father.children=branchArr : '' //给父级添加一个children属性,并赋值
return father.parentId==0; //返回第一层
});
}
console.log(setTreeData(source),'++++++++++++') // 树形数据
// 第二种: for in 方式
function TreeData(source){
let data = source
let oneMenu = [];
let tempObj = {}
for(let k in data){
for (let i in data) { //啥也别说,先赋值一圈
tempObj[data[i].id] = data[i]
}
let objParentId = tempObj[data[k].id].parentId;//外层循环开始,获取当前对象父id
let currentObj = tempObj[data[k].id];//获取当前对象
if(objParentId>0){//当前对象如果不是一级菜单
if(!(child instanceof Array))tempObj[objParentId].child = []; //如果不是数组则进行创建空数组[],防止undefined
tempObj[objParentId].child.push(currentObj)
}else{ //只取一级菜单,此时一级菜单中已经添加了child数组了
oneMenu.push(currentObj)
}
}
return oneMenu;
}
console.log(TreeData(source),'--------------') // 树形数据
</script>
</body>
</html>