Vue将后端数据转成树形结构的方法示例代码

 更新时间:2025年06月14日 10:06:31   作者:ShareJasmine  
vue是一款流行的前端框架,其中很多操作都是基于数组进行的,这篇文章主要介绍了Vue将后端数据转成树形结构的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

1. 前言

需要将后端传来的数据转成嵌套的树形结构,后端数据形式如下:

[
  {
    "id": 48,
    "parentId": 47,
    "workspaceName": "工艺计划书合集",
    "workspaceCode": "A8-B1"
  },
  {
    "id": 47,
    "parentId": null,
    "workspaceName": "工艺计划书",
    "workspaceCode": "A8"
  },
  {
    "id": 26,
    "parentId": null,
    "workspaceName": "0501DKD工作指导书",
    "workspaceCode": "A2"
  },
  {
    "id": 29,
    "parentId": 26,
    "workspaceName": "月度计划工艺包装方案A",
    "workspaceCode": "A2-B1"
  },
  {
    "id": 35,
    "parentId": 26,
    "workspaceName": "月度计划工艺包装方案B",
    "workspaceCode": "A2-B2"
  }
]

2. 思路

首先,这里parentIdnull的是一级父节点,然后其他parentId有值的挂在对应id节点之后,最后整理的结果应该是这样一个效果:

[
  {
    "id": 47,
    "parentId": null,
    "workspaceName": "工艺计划书",
    "workspaceCode": "A8",
    "children": {
      "id": 48,
      "parentId": 47,
      "workspaceName": "工艺计划书合集",
      "workspaceCode": "A8-B1"
    }
  },
  {
    "id": 26,
    "parentId": null,
    "workspaceName": "0501DKD工作指导书",
    "workspaceCode": "A2",
    "children": [
      {
        "id": 29,
        "parentId": 26,
        "workspaceName": "月度计划工艺包装方案A",
        "workspaceCode": "A2-B1"
      },
      {
        "id": 35,
        "parentId": 26,
        "workspaceName": "月度计划工艺包装方案B",
        "workspaceCode": "A2-B2"
      }
    ]
  }
]

3. 代码

第一种是使用ES6的map语法:

function listToTree(data) {
  const map = new Map();
  const tree = [];

  // 第一步:遍历数据,将每一项存入 Map 中,并初始化 children = []
  data.forEach((p) => {
    p.children = [];
    // 将节点的 id 作为 key,整个节点对象作为 value 存入 Map
    map.set(p.id, p);
  });

  // 第二步:再遍历一次数据,根据 parentId 找到父节点,并将当前节点加入父节点的 children
  data.forEach((p) => {
    // 找到父节点,把当前节点挂载为其子节点
    // 注意由于 map 中的值为一个对象,属于引用数据类型,所以这里处理 map,就可以实现 tree 中出现相应的嵌套数据
    if (p.parentId !== null && map.has(p.parentId)) {
      map.get(p.parentId).children.push(p);
    } else {
      // 如果 parentId 为 null 或找不到父节点,则是顶级节点,加入 tree 根节点数组
      tree.push(p);
    }
  });

  return tree;
}

第二种是若依框架的兼容IE浏览器的写法:

/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 */
export function handleTree(data, id, parentId, children) {
  let config = {
    id: id || 'id',
    parentId: parentId || 'parentId',
    childrenList: children || 'children',
  };

  var childrenListMap = {};
  var nodeIds = {};
  var tree = [];

  for (let d of data) {
    let parentId = d[config.parentId];
    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = [];
    }
    nodeIds[d[config.id]] = d;
    childrenListMap[parentId].push(d);
  }

  for (let d of data) {
    let parentId = d[config.parentId];
    if (nodeIds[parentId] == null) {
      tree.push(d);
    }
  }

  for (let t of tree) {
    adaptToChildrenList(t);
  }

  function adaptToChildrenList(o) {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]];
    }
    if (o[config.childrenList]) {
      for (let c of o[config.childrenList]) {
        adaptToChildrenList(c);
      }
    }
  }
  return tree;
}

4. 完整演示Demo

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body></body>

<script>
  const data = [
    {
      id: 48,
      parentId: 47,
      workspaceName: '工艺计划书合集',
      workspaceCode: 'A8-B1',
    },
    {
      id: 47,
      parentId: null,
      workspaceName: '工艺计划书',
      workspaceCode: 'A8',
    },
    {
      id: 26,
      parentId: null,
      workspaceName: '0501DKD工作指导书',
      workspaceCode: 'A2',
    },
    {
      id: 29,
      parentId: 26,
      workspaceName: '月度计划工艺包装方案A',
      workspaceCode: 'A2-B1',
    },
    {
      id: 35,
      parentId: 26,
      workspaceName: '月度计划工艺包装方案B',
      workspaceCode: 'A2-B2',
    },
  ];

  function listToTree(data) {
    const map = new Map();
    const tree = [];

    data.forEach((p) => {
      p.children = [];
      map.set(p.id, p);
    });

    data.forEach((p) => {
      if (p.parentId !== null && map.has(p.parentId)) {
        map.get(p.parentId).children.push(p);
      } else {
        tree.push(p);
      }
    });

    return tree;
  }

  const result = listToTree(data);

  console.log('result:', result);
</script>

</html>

总结

到此这篇关于Vue将后端数据转成树形结构的文章就介绍到这了,更多相关Vue后端数据转成树形结构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 实例讲解v-if和v-show的区别

    实例讲解v-if和v-show的区别

    今天小编就为大家分享一篇关于实例讲解v-if和v-show的区别,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 详解通过JSON数据使用VUE.JS

    详解通过JSON数据使用VUE.JS

    本篇文章主要介绍了详解通过JSON数据使用VUE.JS,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Vue mixin实现组件功能复用示例详解

    Vue mixin实现组件功能复用示例详解

    这篇文章主要为大家介绍了Vue mixin实现组件功能复用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Vue中的计算属性与监听属性

    Vue中的计算属性与监听属性

    这篇文章介绍了Vue中的计算属性与监听属性,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • IE9 elementUI文件上传的问题解决

    IE9 elementUI文件上传的问题解决

    这篇文章主要介绍了IE9 elementUI文件上传的问题解决,有需要了解IE9 elementUI文件上传的朋友可参考。希望此文章对各位有所帮助
    2018-10-10
  • vue+webpack中配置ESLint

    vue+webpack中配置ESLint

    这篇文章主要介绍了vue+webpack中配置ESLint,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • vue parseHTML 函数源码解析

    vue parseHTML 函数源码解析

    这篇文章主要为大家介绍了vue parseHTML函数的源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Vue前端路由hash与history差异深入了解

    Vue前端路由hash与history差异深入了解

    这篇文章主要为大家介绍了Vue前端路由hash与history差异的深入了解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Vue如何实现分页功能代码实例

    Vue如何实现分页功能代码实例

    这篇文章主要给大家介绍了关于Vue如何实现分页功能的相关资料,Vue分页功能的实现需要前端和后端共同配合完成,文中通过代码实例介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • vue侧边栏动态生成下级菜单的方法

    vue侧边栏动态生成下级菜单的方法

    今天小编就为大家分享一篇vue侧边栏动态生成下级菜单的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09

最新评论