路由修正
This commit is contained in:
@@ -8,6 +8,7 @@ import type { Router, NavigationGuardNext, RouteLocationNormalized } from 'vue-r
|
||||
import type { Store } from 'vuex';
|
||||
import { AuthState } from '@/store/modules/auth';
|
||||
import { systemOverviewApi } from '@/apis/system/overview';
|
||||
import { routes as staticRoutes } from '@/router';
|
||||
|
||||
/**
|
||||
* 白名单路由 - 无需登录即可访问
|
||||
@@ -50,8 +51,9 @@ export function setupRouterGuards(router: Router, store: Store<any>) {
|
||||
// 设置页面标题
|
||||
setPageTitle(to.meta?.title as string);
|
||||
|
||||
// 统计PV:对path以"/"开头的路由进行统计
|
||||
if (to.path.startsWith('/')) {
|
||||
// 统计PV:对path以"/"开头的路由进行统计 非静态路由
|
||||
const isStaticRoute = staticRoutes.some(route => route.path === to.matched[0]?.path);
|
||||
if (!isStaticRoute && to.path.startsWith('/')) {
|
||||
systemOverviewApi.trackVisit().catch(() => {
|
||||
// 统计失败不影响正常页面使用
|
||||
});
|
||||
|
||||
@@ -186,9 +186,12 @@ function generateRouteFromMenu(menu: SysMenu, isTopLevel = true): RouteRecordRaw
|
||||
}
|
||||
});
|
||||
|
||||
// 当前菜单指定了页面组件时,即使存在子菜单也应当渲染该页面
|
||||
// 但如果 component 是布局组件,则不应该创建 path: '' 的子路由(因为布局组件已经是父路由的组件了)
|
||||
if (menu.component && !isComponentLayout) {
|
||||
// 当前菜单指定了页面组件时,如果存在“普通子菜单”(非 PAGE 类型)
|
||||
// 则需要创建一个默认子路由来承载当前菜单的页面组件,
|
||||
// 这样父级既能作为分组,又能渲染自己的页面。
|
||||
// 如果只有 PAGE 类型子菜单,则直接使用当前路由组件,而不再包一层 `_page`,
|
||||
// 避免多出一层嵌套导致 matched 结构过深。
|
||||
if (menu.component && !isComponentLayout && normalChildren.length > 0) {
|
||||
route.children!.push({
|
||||
path: '',
|
||||
name: `${menu.menuID}_page`,
|
||||
|
||||
@@ -1,33 +1,40 @@
|
||||
import { RouteRecordRaw, RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
export function getParentChildrenRoutes(route: RouteLocationNormalized): RouteRecordRaw[] {
|
||||
// 判断是否有父节点(至少需要2个匹配的路由)
|
||||
if (route.matched.length < 2) {
|
||||
// 没有任何匹配路由,直接返回空
|
||||
if (!route.matched || route.matched.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 获取倒数第二个匹配的路由(父路由)
|
||||
const parentRoute = route.matched[route.matched.length - 2];
|
||||
|
||||
// 检查父路由是否有子路由
|
||||
if (!parentRoute?.children || parentRoute.children.length === 0) {
|
||||
return [];
|
||||
|
||||
// 从当前路由向上查找,找到第一个“有可见子路由”的父级
|
||||
for (let i = route.matched.length - 2; i >= 0; i--) {
|
||||
const parentRoute = route.matched[i];
|
||||
const children = parentRoute?.children || [];
|
||||
|
||||
if (!children || children.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const visibleChildren = children.filter((child: RouteRecordRaw) => {
|
||||
// 必须有 title
|
||||
if (!child.meta?.title) {
|
||||
return false;
|
||||
}
|
||||
// 排除 path 为空字符串的子路由(通常是默认子路由)
|
||||
if (child.path === '' || child.path === undefined) {
|
||||
return false;
|
||||
}
|
||||
// 排除 name 以 _page 结尾的子路由(父路由的默认子路由)
|
||||
if (typeof child.name === 'string' && child.name.endsWith('_page')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (visibleChildren.length > 0) {
|
||||
return visibleChildren;
|
||||
}
|
||||
}
|
||||
|
||||
// 返回有 title 的子路由,但排除父路由本身(path 为空字符串或 name 以 _page 结尾的子路由)
|
||||
return parentRoute.children.filter((child: RouteRecordRaw) => {
|
||||
// 必须有 title
|
||||
if (!child.meta?.title) {
|
||||
return false;
|
||||
}
|
||||
// 排除 path 为空字符串的子路由(代表父路由本身)
|
||||
if (child.path === '' || child.path === undefined) {
|
||||
return false;
|
||||
}
|
||||
// 排除 name 以 _page 结尾的子路由(父路由的默认子路由)
|
||||
if (typeof child.name === 'string' && child.name.endsWith('_page')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return [];
|
||||
}
|
||||
Reference in New Issue
Block a user