diff --git a/src/components/AppLayout/AppLayout.vue b/src/components/AppLayout/AppLayout.vue index 17e2771..7a2cea3 100644 --- a/src/components/AppLayout/AppLayout.vue +++ b/src/components/AppLayout/AppLayout.vue @@ -69,18 +69,28 @@ const breadcrumbItems = computed(() => { const currentPath = route.path // 工作台首页不显示中间层级 if (currentPath === '/' || currentPath === '/dashboard') return [] - // DFS 找父级链 + // DFS 找父级链: 父菜单(有 children)的 path 是第一个子菜单的 path(见 + // resolveMenuItem), 不能用 path 前缀短路命中父菜单, 必须先递归子树, + // 子树没命中才考虑父菜单自身。 function findChain(items: MenuItem[], target: string, chain: MenuItem[]): boolean { for (const item of items) { - if (item.path === target || (item.path !== '/' && target.startsWith(item.path))) { + // 叶子节点: path 精确匹配 + if (!item.children?.length) { + if (item.path === target) { + chain.push(item) + return true + } + continue + } + // 父节点: 先递归子树 + chain.push(item) + if (findChain(item.children, target, chain)) return true + chain.pop() + // 子树没命中, 看父节点自身 path 是否是 target 的前缀(详情页场景) + if (item.path !== '/' && target.startsWith(item.path)) { chain.push(item) return true } - if (item.children?.length) { - chain.push(item) - if (findChain(item.children, target, chain)) return true - chain.pop() - } } return false }