🧭 动态路由与权限管理指南
🔑 权限配置流程
1️⃣ 中台权限配置
在业务中台-系统设置-应用管理页面添加应用、菜单、功能按钮:

2️⃣ 角色授权配置
在业务中台-用户中心-角色管理页面选择角色并进行权限授权:

📁 路由文件配置
⚙️ 主路由文件 (index.ts)
创建 routers/index.ts 文件,配置路由实例和路由守卫:
ts
import { AuthStore, initDynamicRouter } from '@pt/common-ui';
import { createRouter, createWebHashHistory } from 'vue-router';
import { staticRouter } from './staticRouter';
import { storage } from '@pt/utils';
import { LOGIN_URL, ROUTER_WHITE_LIST } from '@/config';
// 🔄 创建路由实例
const router = createRouter({
history: createWebHashHistory(),
routes: [...staticRouter],
strict: false,
scrollBehavior: () => ({ left: 0, top: 0 }),
});
/**
* @description 重置路由
* */
export const resetRouter = () => {
const authStore = AuthStore();
authStore.flatMenuListGet.forEach((route) => {
const { name } = route;
if (name && router.hasRoute(name)) router.removeRoute(name);
});
};
// 🔍 引入 views 文件夹下所有 vue 文件
// @ts-ignore
const modules = import.meta.glob('@example/views/**/*.vue');
// 🛡️ 路由守卫配置
router.beforeEach(async (to, from, next) => {
const cookie_token = storage.get('token');
const cookie_userInfoStr = storage.get('userInfo');
const authStore = AuthStore();
authStore.setRouteName(to.name as string);
// 2.动态设置标题
// const title = import.meta.env.VITE_GLOB_APP_TITLE;
// document.title = to.meta.title ? `${to.meta.title} - ${title}` : title;
// 3.判断是访问登陆页,有 Token 就在当前页面,没有 Token 重置路由并放行到登陆页
if (to.path.toLocaleLowerCase() === LOGIN_URL) {
if (cookie_token && cookie_userInfoStr) return next(from.fullPath);
storage.clear();
resetRouter();
return next();
}
// 4. 白名单可以直接访问
if (ROUTER_WHITE_LIST.includes(to.path)) {
return next();
}
// 5.判断是否有 Token,没有重定向到 login
if (!cookie_token || !cookie_userInfoStr)
return next({ path: LOGIN_URL, replace: true });
// 6.如果没有菜单列表,就重新请求菜单列表并添加动态路由
authStore.setRouteName(to.name as string);
if (!authStore.authMenuListGet.length) {
await initDynamicRouter(router, {
parentRouteName: 'layout',
resolveComponent: (path: string) => {
return () => modules['/example/src/views' + path + '.vue']?.();
},
goLogin: () => {
next({ path: LOGIN_URL, replace: true });
},
});
return next({ ...to, replace: true });
}
// 7.正常访问页面
next();
});
export default router;📊 静态路由文件 (staticRouter.ts)
创建 src/routers/staticRouter.ts 文件,配置基础路由结构:
ts
import { RouteRecordRaw } from 'vue-router';
import { HOME_URL, LOGIN_URL } from '../config';
/**
* staticRouter(静态路由)
*/
export const staticRouter: RouteRecordRaw[] = [
{
path: '/',
redirect: HOME_URL,
},
{
path: LOGIN_URL,
name: 'login',
component: () => import('../views/login/index.vue'),
},
{
path: '/layout',
name: 'layout',
component: () => import('../layouts/index.vue'),
redirect: HOME_URL,
children: [
/* {
path: '/components',
component: () => import('../views/ComponentsDemo.vue'),
name: 'components',
},
{
path: '/auth',
component: () => import('../views/AuthDemo.vue'),
name: 'auth',
}, */
],
},
];⚓ 基础配置文件 (config/index.ts)
创建 src/config/index.ts 文件,定义基础路由配置:
ts
// * 首页地址(默认)
export const HOME_URL: string = '/components';
// * 登录页地址(默认)
export const LOGIN_URL: string = '/login';
// * Tabs(白名单地址,不需要添加到 tabs 的路由地址)
export const TABS_WHITE_LIST: string[] = ['/403', '/404', '/500', LOGIN_URL];
// * 路由白名单地址,不需要权限就可以访问(必须是本地存在的路由 staticRouter.ts)
export const ROUTER_WHITE_LIST: string[] = [
'/register',
'/forgotPassword',
'/login/agreement',
'/login/privacy',
'/svg-preview/index',
'/demo2',
'/demo3',
];🌟 主要功能说明
- 🔐 权限控制:通过业务中台配置菜单和功能权限
- 🔄 动态路由:使用
initDynamicRouter方法动态加载路由 - 🛡️ 路由守卫:自动处理登录状态、权限检查和路由跳转
- 🗂️ 代码组织:将路由配置拆分为主文件、静态路由和基础配置
📝 最佳实践
- 将所有页面组件放在
views目录下,便于动态路由自动加载 - 使用约定式路径命名,保持与后台权限配置的一致性
- 合理配置白名单,避免公共页面也需要权限验证
- 使用路由懒加载提高性能