Vue后台管理项目经常有权限控制,不同角色使用不同权限,常用方法就是用addRoutes来动态添加路由,但有两个问题是官方文档上找不到解决方案的
- 角色切换,addRoutes提示有重复的路由,无法删除之前角色的路由
- 使用router.matcher = new Router().matcher替换掉旧的路由
- 刷新页面,动态路由消失,提示404
- 将404页面放在动态路由中加载,即获取动态路由后,
push上404页,这样就完美解决了
- 将404页面放在动态路由中加载,即获取动态路由后,
//在router模块的index.js对路由进行拆分
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
//常量路由(即所有人都能看到的路由)
export const constRoutes = []
//异步理由:不同的用户(角色),需要过滤筛选出的路由,称之为异步路由
export const asyncRoutes = []
// 404界面,一定要放在最后
export const anyRoutes = {path'*',redirect:'/',hidden:true}
//定义创建路由的函数
const createRouter = () => new Router({
scrollBehavior: () => ({ y: 0 }),//路由跳转回到顶部
routes: constantRoutes
})
//创建路由
const router = createRouter()
//在store获取用户信息的模块中
import { constantRoutes,asyncRoutes,anyRoutes } from '@/router'
import router from '@/router'
const getDefaultState = () => {
return {
//用户最终需要展示全部路由
allRoutes:[]
}
}
const state = getDefaultState()
const actions = {
async getUserInfo(){
if (result.code === 200) {
const { data } = result
//服务器返回的权限信息【根据不同的角色:返回的路由权限信息】
const { routes } = data
commit('SET_ASYNCROUTES', computedAsyncRoutes(asyncRoutes,routes))
return 'ok'
} else {
return Promise.reject(new Error('fail'))
}
},
}
const mutations = {
SET_ASYNCROUTES: (state,asyncRoutes) => {
// 将该角色能访问的异步路由与常量路由及404路由合并
state.allRoutes = constRoutes.concat(asyncRoutes,anyRoutes)
router.matcher = new Router().matcher //清空之前的旧路由
router.addRoutes(state.allRoutes) //
}
}
// 计算出当前用户所能访问的路由
function computedAsyncRoutes(asyncRoutes,routes){
// 返回该角色能访问到的路由数组
return asyncRoutes.filter(item => {
// routes数组中的内容是该角色的所能访问的路由的名字
if(routes.indexOf(item.name) != -1){
//递归
if(item.children && item.children.length){
// 如果有子路由,子路由中能访问的路由也需要计算
item.children = computedAsyncRoutes(item.children,routes)
}
return true
}
})
}
注意: 在vue-router 3.5.0版本中,router.addRoutes被标记为不推荐的API,建议使用 router.addRoute 在vue-router 4.x 中,router.addRoutes被删除,只能使用 router.addRoute