Procházet zdrojové kódy

fix(路由): 修复面包屑和侧边栏菜单显示问题

修复面包屑导航中过滤条件错误导致部分路由不显示的问题
优化侧边栏菜单逻辑,仅显示非隐藏子菜单
调整路由扁平化逻辑,正确处理隐藏子菜单的路由
piks před 5 dny
rodič
revize
eab4c60025

+ 1 - 1
src/components/Breadcrumb/index.vue

@@ -13,7 +13,7 @@ interface BreadcrumbItem {
 }
 
 const breadcrumbs = computed<BreadcrumbItem[]>(() => {
-  const matched = route.matched.filter(item => item.meta?.title && !item.meta?.hidden)
+  const matched = route.matched.filter(item => item.meta?.title)
 
   return matched.map((item, index) => ({
     title: item.meta?.title as string,

+ 5 - 5
src/layout/components/Sidebar/SidebarItem.vue

@@ -11,16 +11,16 @@ const props = withDefaults(defineProps<Props>(), {
   basePath: ''
 })
 
-// 判断是否有可见的子菜单
-const hasChildren = computed(() => {
-  return props.item.children && props.item.children.length > 0
-})
-
 // 过滤隐藏的子菜单
 const visibleChildren = computed(() => {
   return props.item.children?.filter(child => !child.meta?.hidden) || []
 })
 
+// 判断是否有可见的子菜单
+const hasChildren = computed(() => {
+  return visibleChildren.value.length > 0
+})
+
 // 解决路径
 const resolvePath = computed(() => {
   return resolveBasePath(props.item.path)

+ 12 - 4
src/mock/index.ts

@@ -22,10 +22,18 @@ const allAsyncRoutes: MenuItem[] = [
     meta: { title: '首页', icon: 'HomeFilled', roles: ['admin', 'editor'] }
   },
   {
-    path:"/sdk",
-    name:"Sdk",
-    component:"sdk/index",
-    meta:{title:"SDK管理",icon:"Box",roles:["admin"]}
+    path: "/sdk",
+    name: "Sdk",
+    component: "sdk/index",
+    meta: { title: "SDK管理", icon: "Box", roles: ["admin"] },
+    children: [
+      {
+        path: "detail",
+        name: "SdkDetail",
+        component: 'sdk/detail',
+        meta: { title: "SDK管理详情", icon: "Box", roles: ["admin"], hidden: true },
+      }
+    ]
   },
   {
     path: '/system',

+ 15 - 6
src/utils/routeHelper.ts

@@ -30,20 +30,29 @@ export function resolvePath(basePath: string, routePath: string): string {
  * 将嵌套菜单数据扁平化为 Vue Router 可用的路由配置
  * 所有动态路由最终挂载在 Root(Layout)下
  */
-export function flattenMenuToRoutes(
-  menuItems: MenuItem[],
-  parentPath = ''
-): RouteRecordRaw[] {
+export function flattenMenuToRoutes(menuItems: MenuItem[], parentPath = ''): RouteRecordRaw[] {
   const routes: RouteRecordRaw[] = []
 
   menuItems.forEach(item => {
     const fullPath = resolvePath(parentPath, item.path)
 
-    if (item.children && item.children.length > 0) {
+    // 过滤掉 hidden 的子菜单
+    const visibleChildren = item.children?.filter(child => !child.meta?.hidden) || []
+
+    if (visibleChildren.length > 0) {
       // 父级菜单:注册 redirect 路由,再递归处理子项
       routes.push({
         path: fullPath,
-        redirect: item.redirect || resolvePath(fullPath, item.children[0].path),
+        redirect: item.redirect || resolvePath(fullPath, visibleChildren[0].path),
+        meta: item.meta
+      } as RouteRecordRaw)
+      routes.push(...flattenMenuToRoutes(visibleChildren, fullPath))
+    } else if (item.children && item.children.length > 0) {
+      // 有子菜单但都是隐藏的:注册父级路由 + 递归处理隐藏子项
+      routes.push({
+        path: fullPath,
+        name: item.name,
+        component: loadComponent(item.component!),
         meta: item.meta
       } as RouteRecordRaw)
       routes.push(...flattenMenuToRoutes(item.children, fullPath))