b站很多实战教程,尤其是后台管理系统的教程基本上只教了些皮毛,很多实用性强的功能基本上没有说,这也是我遇到这种问题无从下手的原因,这里推荐一个教程,也是b站上可看。https://www.bilibili.com/video/BV1zJ411g7Fx 不敢说他教的有多好,但是他的教学内容很接近实际开发了,其中就包含了动态路由。
前期很迷茫,看了许许多多的博客帖子,基本上所有的教程都围绕这一页面https://juejin.im/post/6844903478880370701,我的思路基本上就是照着这个来的。
首先写好静态和动态的路由(并非最终路由,仅供参考用)
export const constantRouterMap = [{ //静态路由
path: '/',
redirect: '/login'
},
{
path: '/login',
component: Login
},
]
export const asyncRouterMap = [{ //动态路由
name: 'home',
path: '/home',
component: Home,
meta: {
title: '首页',
roles: ['admin', 'editor', 'list']
},
children: [{
name: 'user',
path: '/user',
key: '1',
components: User,
meta: {
title: '用户',
roles: ['admin', 'editor']
}
},
{
name: 'shop',
path: '/shop',
key: '2',
components: Shop,
meta: {
title: '商品',
roles: ['admin', 'editor', 'list']
}
},
{
name: 'rights',
path: '/rights',
key: '3',
components: Rights,
meta: {
title: '权限',
roles: ['admin', 'editor']
}
},
{
name: 'operate',
path: '/operate',
key: '4',
components: Operate,
meta: {
title: '设置',
roles: ['admin']
}
},
]
}, {
path: '*',
component: NotFound
}]
const router = new VueRouter({
routes: constantRouterMap,
})
export default router
之后设置路由导航守卫
router.beforeEach((to, from, next) => {
if (getToken()) { //获取token
if (to.path === '/login') {
store.state.userinfo = [] //调试用,在登录页清空用户数据
store.state.addRouters = []
sessionStorage.clear()
next()
} else {
if (sessionStorage.getItem('roles')) { //有角色信息,可直接跳转
next()
} else {
axios({ //没有角色信息,根据用户token获取角色
method: "post",
url: "/userrole",
data: {
token: sessionStorage.getItem('token')
}
}).then(data => {
const userRole = data.data //保存用户角色
store.dispatch('GenerateRoutes', userRole).then(() => { //根据用户角色生成路由
const newRouter = store.state.addRouters
router.addRoutes(newRouter) //添加路由
sessionStorage.setItem('roles', userRole) //将角色添加至session中
sessionStorage.setItem('router', JSON.stringify(store.state.routers))
next({...to, replace: true })
}).catch(
(err) => {
if (err) {
Message.error('网络错误,请重试')
setTimeout(() => {
sessionStorage.removeItem('roles')
setTimeout(() => {
location.reload()
}, 0)
NProgress.done()
}, 2000)
}
}
)
});
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next('/login')
}
}
})
GenerateRoutes:
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const roles = data //保存传入的角色
let accessedRouters //设置临时路由
if (roles.includes('admin') === true) {
accessedRouters = asyncRouterMap //管理员赋予所有权限
} else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles) //非管理员筛选权限
}
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}
filterAsyncRouter和hasPermission:
function filterAsyncRouter(asyncRouterMap, roles) { //传入两个参数,路由和角色
const accessedRouters = asyncRouterMap.filter(route => {
if (hasPermission(roles, route)) { //若得到true,执行下一步
if (route.children && route.children.length) { //判断是否存在子路由
route.children = filterAsyncRouter(route.children, roles) //对子路由进行过滤
}
return true
}
return false
})
return accessedRouters
}
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) { //需要角色的路由
return roles.some(role => route.meta.roles.includes(role) === true) //存在该角色,返回true,否则返回false
} else {
return true
}
}
SET_ROUTERS:
SET_ROUTERS: (state, routers) => {
state.addRouters = routers //将筛选后的权限添加到addRouters内
state.routers = constantRouterMap.concat(routers) //最终路由为默认路由+筛选后的路由
}
admin界面:
editor界面:
list界面: