fix: 扁平路由转数组优化
This commit is contained in:
parent
44ad51c7b0
commit
21a4af6ab6
@ -16,6 +16,7 @@
|
||||
* | |-- 子节点2-1: '010201'
|
||||
* | |-- 子节点2-2: '010202'
|
||||
* 当然,你们也可以自行设计id结构,只要保证id的唯一性即可,最后接口返回的是一个树形结构
|
||||
* 注意:节点id不能与parentId相同,否则在遍历路由树的时候会出现无限循环,在设计id的时候需要避免节点增多而导致id相同的情况
|
||||
*
|
||||
*
|
||||
* 路由meta对象参数,我们通常将属性放到meta对象中
|
||||
|
||||
@ -128,23 +128,49 @@ export function deepClone(data: any) {
|
||||
* @returns 树形结构
|
||||
*/
|
||||
export const buildTreeOptimized = (nodes: Menu.MenuOptions[]) => {
|
||||
const nodeMap = new Map(); // 哈希映射存储节点引用
|
||||
const nodeMap = new Map(); // 哈希表存储所有节点
|
||||
const roots = []; // 存储顶层节点
|
||||
const duplicates = new Set(); // 检测重复ID
|
||||
|
||||
// 单次遍历构建结构(兼容乱序数据)
|
||||
// 第一次遍历: 注册所有节点 & 检测重复
|
||||
for (const node of nodes) {
|
||||
const { id, parentId } = node;
|
||||
node.children = []; // 初始化子节点数组
|
||||
const id = node.id;
|
||||
|
||||
// 将当前节点存入哈希表
|
||||
// 循环引用检测
|
||||
if (node.id === node.parentId) {
|
||||
throw new Error(`循环引用: ${node.id} -> ${node.parentId}`);
|
||||
}
|
||||
|
||||
// 重复ID检测
|
||||
if (nodeMap.has(id)) {
|
||||
duplicates.add(id);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 初始化子节点数组
|
||||
node.children = [];
|
||||
nodeMap.set(id, node);
|
||||
}
|
||||
|
||||
// 输出重复警告
|
||||
if (duplicates.size > 0) {
|
||||
console.warn(`检测到重复ID: ${Array.from(duplicates).join(", ")}`);
|
||||
}
|
||||
|
||||
// 第二次遍历: 构建树结构
|
||||
for (const node of nodes) {
|
||||
const { parentId } = node;
|
||||
|
||||
// 跳过已处理的重复节点
|
||||
if (duplicates.has(node.id)) continue;
|
||||
|
||||
// 处理父子关系
|
||||
if (parentId === "0") {
|
||||
roots.push(node); // 顶层节点直接加入结果
|
||||
} else {
|
||||
roots.push(node); // 顶层节点
|
||||
} else if (parentId) {
|
||||
const parent = nodeMap.get(parentId);
|
||||
parent?.children.push(node); // 子节点挂载到父级
|
||||
parent?.children.push(node); // 挂载子节点
|
||||
} else {
|
||||
console.warn(`孤儿节点 ${node.id}: parentId为空`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user