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

32次阅读

共计 1249 个字符,预计需要花费 4 分钟才能阅读完成。

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

参考:一位大佬的

正文完
 0