前端将后端返回的数据处理成树形结构数据

javascript/jquery

浏览数:104

2019-9-1

AD:资源代下载服务

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的初始化了一遍。

参考:一位大佬的

作者:yang