demo
方法一 递归
数据
var data = [
{
"area_id": 5,
"name": "广东省",
"parent_id": 0,
},
{
"area_id": 6,
"name": "广州市",
"parent_id": 5,
},
{
"area_id": 7,
"name": "深圳市",
"parent_id": 5,
},
{
"area_id": 4,
"name": "北京市",
"parent_id": 3,
},
{
"area_id": 3,
"name": "北京",
"parent_id": 0,
},
{
"area_id": 2,
"name": "测试子地区",
"parent_id": 1,
},
{
"area_id": 1,
"name": "测试地区",
"parent_id": 0,
}
]
function toTreeData(data,pid){
function tree(id){
let arr = []
data.filter(item =>{
return item.parent_id ==id
}).forEach(item => {
arr.push({
area_id: item.area_id,
label:item.name,
children: tree(item.area_id)
})
})
return arr
}
return tree(pid)// 第一级节点的父id,是null或者0,视情况传入
}
不过,该方法有个缺点,在我使用组件的时候需要的数据结构中,如果子级没有数据children返回[]。
需要将数据整理树形结构的主要在菜单栏或分类的树形结构上,当然还有像省市这种有从属关系的结构。
方法二——对象
function setTreeData(arr){
// 删除所有的children,以防止多次调用
arr.forEach(function(item){
delete item.children
});
let map = {};//构建map
arr.forEach(i=>{
map[i.area_id]=i; //构建以area_id为键 当前数据为值
});
let treeData = [];
arr.forEach(child => {
const mapItem = map[child.parent_id];//判断当前数据的parent_id是否存在map中
if(mapItem){//存在则表示当前数据不是最顶层的数据
//注意: 这里的map中的数据是引用了arr的它的指向还是arr,当mapItem改变时arr也会改变,踩坑点
(mapItem.children || (mapItem.children = [])).push(child);//这里判断mapItem中是否存在child
}else {//不存在则是顶层数据
treeData.push(child)
}
})
return treeData
}
console.log(setTreeData(data))
这种方法有一种容易犯错的地方,就是它会改变原数据,我就在这里踩了好久的坑,所以一开始采用了删除children的初始化了一遍。
参考:一位大佬的
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。