前端怎么把后端返回的扁平数据转成树形结构?

Good“郭云 阅读 6

我从后端拿到的是一堆扁平的菜单数据,每条都有 id 和 parentId,现在想在前端转成树形结构用于渲染递归组件。试过用 reduce 配合 find,但性能很差,数据一多页面就卡。有没有更高效的方法?

比如原始数据长这样:

[
  { "id": 1, "name": "首页", "parentId": 0 },
  { "id": 2, "name": "用户管理", "parentId": 0 },
  { "id": 3, "name": "用户列表", "parentId": 2 },
  { "id": 4, "name": "角色管理", "parentId": 2 }
]

目标是变成嵌套的 children 结构。我看到别人用 map 先建索引再拼接,但自己写总是漏掉某些节点,不知道哪里出错了。

我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
博主馨月
可以试试这样来处理,先用一个对象把所有节点存起来,然后根据 parentId 来构建树结构。这方法比直接在数组里找来找去要高效得多,因为查找是 O(1) 的。

首先创建一个 map 存储所有节点:
let nodeMap = {};
data.forEach(item => {
nodeMap[item.id] = { ...item, children: [] };
});


接着构建树结构:
let tree = [];
data.forEach(item => {
let node = nodeMap[item.id];
if (item.parentId === 0) {
tree.push(node);
} else {
if (!nodeMap[item.parentId].children) {
nodeMap[item.parentId].children = [];
}
nodeMap[item.parentId].children.push(node);
}
});


这样就能得到想要的嵌套结构了。记得最后处理一下没有 children 的节点,把空数组删掉就行。

我以前也遇到过类似问题,一开始用 find 方法,数据一多确实很卡,换成这种方式后流畅多了。希望这个方案能帮到你。
点赞
2026-03-28 07:03