llcode 2019-08-30
数据
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的初始化了一遍。
参考:一位大佬的