系列文档目录
客制Form组件
国际化
配置文件
文章目录
目录
前言
在前一章节中,主要探讨了如何动态增加路由配置。在实际使用过程中,发现了一个问题:当用户切换账号时,之前账号的路由仍然保留在路由表中。这导致即使菜单中没有对应的路由,用户也可以通过直接在地址栏输入网址来访问该页面,从而可能引发权限问题。为了避免这一问题,本章节将重点讲解如何动态移除路由,确保在用户切换账号时,旧账号的路由能够被正确清理,从而保障系统的安全性和权限管理的准确性。
删除路由
1.路由变化状况
使用 admin 账号登录后,再切换至 user 账号登录时,发现路由(Router)未发生变化。原因是之前登录账号的动态路由仍然保留在路由表中,因此需要将其删除。
2.官方说明文档
有几个不同的方法来删除现有的路由:
-
通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由:
router.addRoute({ path: '/about', name: 'about', component: About }) // 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的 router.addRoute({ path: '/other', name: 'about', component: Other })
-
通过调用
router.addRoute()
返回的回调:const removeRoute = router.addRoute(routeRecord) removeRoute() // 删除路由如果存在的话
当路由没有名称时,这很有用。
-
通过使用
router.removeRoute()
按名称删除路由:router.addRoute({ path: '/about', name: 'about', component: About }) // 删除路由 router.removeRoute('about')
需要注意的是,如果你想使用这个功能,但又想避免名字的冲突,可以在路由中使用
Symbol
作为名字。
当路由被删除时,所有的别名和子路由也会被同时删除
3.动态删除路由
在使用 addRouter 函数动态增加路由之前,先通过 router.removeRoute 方法动态移除已存在的路由。在执行动态移除路由操作时,需要注意排除一些不需要移除的路由项。
在本案例中,通过调用 router.removeRoute() 方法按路由名称进行删除操作,以下是关键代码示例:
// 增加删除路由
routerList.forEach((item:any) => {
if (item.name === 'main'
|| item.name === 'home'
|| item.name === '404'
|| item.name === 'login'
|| item.name === 'error'
|| item.name === 'undefined'
|| item.path === '/'
|| item.path === '/main')
return
router.removeRoute(item.name)
});
以下是优化后的 src/stores/index.ts 完整代码示例:
// src/stores/index.ts
import { defineStore } from 'pinia';
import router from '../router';
import type { Component } from 'vue';
type Modules = Record<string, () => Promise<{ default: Component }>>;
// 定义公共 store
export const useAllDataStore = defineStore('useAllData', {
// 定义状态
state: () => ({
isCollapse: false, // 定义初始状态
username: '',
token_key: '',
menuData:[],
}),
// 定义 actions
actions: {
// 设置用户名
setUsername(username: string) {
this.username = username;
},
// 获取用户名
getUsername(): string {
return this.username;
},
// 设置 token_key
setTokenKey(token_key: string) {
this.token_key = token_key;
},
// 获取 token_key
getTokenKey(): string {
return this.token_key;
},
// 设置菜单数据
setMenuData(menuData: any){
addRouter(menuData)
this.menuData = menuData
},
// 获取菜单数据
getMenuData(): [] {
return this.menuData;
},
},
persist: {
enabled: true,
strategies: [
{
key: 'useAllData-store',
storage: localStorage,
paths: ['token_key','menuData'], // 指定需要持久化的字段
},
],
},
});
function addRouter(menuData: any){
const routerList=router.getRoutes()
const modules: Modules = import.meta.glob('../views/**/*.vue') as Modules;
const routerArr=[]
menuData.forEach((item:any) => {
// console.log(item)
if(item.children){
item.children.forEach((child:any) => {
const componentPath = `../${child.path}.vue`;
const module = modules[componentPath];
if (module) {
/*
module().then(({ default: component }) => {
child.component = component;
});
*/
child.component = module;
routerArr.push(child)
}
});
}
else
{
const componentPath = `../${item.path}.vue`;
const module = modules[componentPath];
if(module)
{
item.component = module;
routerArr.push(item)
}
}
});
// 增加删除路由
routerList.forEach((item:any) => {
if (item.name === 'main'
|| item.name === 'home'
|| item.name === '404'
|| item.name === 'login'
|| item.name === 'error'
|| item.name === 'undefined'
|| item.path === '/'
|| item.path === '/main')
return
router.removeRoute(item.name)
});
routerArr.forEach((item:any) => {
router.addRoute('main',
{
path: item.index,
name: item.label,
component: item.component,
});
})
const routerListLast=router.getRoutes()
console.log(routerListLast)
}
export function ReloadData() {
const store = useAllDataStore();
const menuData = store.getMenuData();
addRouter(menuData);
}
4.演示效果
使用 admin 账号登录时,系统应根据 admin 角色的权限动态加载对应的路由,满足预期。
使用 user账号登录时,系统应根据 user角色的权限动态加载对应的路由,满足预期。
后续
下一章节重点讨论路由守卫