有时候后端会给一个一维数组来让前端渲染一个树形结构菜单,所以参考网上的一些方法,觉得下面这个方法不错,就记录下来了
下面是接口返回的一维线性数组
let data=[
{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},
];
然后转成如图这样的树形数据结构
为了防止修改源数据,所以我们用野路子
JSON.parse(JSON.stingify(arr))
将源数据深度克隆一份,然后再变成树形结构,原理就是将数组的每一项都去循环数组里对比一遍,如果自己的parentId和对比的item的id一样,那么自己就是这一项的children,可以用filter方法直接过滤出来
let data=[
{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},
];
function treeData(arr){
let cloneData = JSON.parse(JSON.stringify(arr)) // 对源数据深度克隆
return cloneData.filter(father=>{
let branchArr = cloneData.filter(child=>father.id == child.parentId) //返回每一项的子级数组
branchArr.length>0 ? father.children = branchArr : '' //如果存在子级,则给父级添加一个children属性,并赋值
return father.parentId==0; //返回第一层
});
}
console.log(treeData(data));