工作中经常会遇到用户权限效验的需求,下面案例使用的是静态路由加动态路由,静态路由就是放一些常用的路由,例如登陆,注册,错误页面等,动态路由就是存放需要验证的路由。
动态路由的注入使用addRoutes,但是这种注入的路由,使用this.$router.options.routes是获取不到的,因为本案例的左侧菜单也是根据动态路由生成的,后面会注明解决办法
路由代码
//静态路由 export const routes = [ { path: '/', name: 'layout', component: Layout, redirect: '/home', hidden: true }, { path: '/login', name: 'Login', component: Login, hidden: true }, { path: '/error', name: 'error', hidden: true, component: Layout, children: [ { path: '/error/404', component: notFound, name: "notFound", } ], }, ] //动态路由 export const asyncRoutes = [ { path: '/home', name: 'home', redirect: '/home/index', component: Layout, children: [ { path: '/home/index', component: Home, name: "homeIndex", meta: { title: '首页', icon: 'md-home', } } ], }, { path: '/admin', name: 'admin', redirect: '/admin/list', component: Layout, children: [ { path: '/admin/list', component: AdminUser, name: "adminList", meta: { title: '管理员管理', icon: 'md-ribbon', roles: ['admin'] } } ], }, //404页面一定要写在动态路由中,不然刷新后进入的就是404页面 { path: '*', component: notFound, hidden: true, redirect: '/error/404' }, ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) const notAuthRouter = ['/login'] router.beforeEach(async (to, from, next) => { ViewUI.LoadingBar.start() //获取存储的token const token = localStorage.getItem('user_token') //拿到token后验证token是否正确 var user = await store.dispatch('user/set_user') if (user && user.username) { //走到这里说明用户的token是正确的,并且没有过期,存储token,当然也可以不存储。 store.commit('user/SET_TOKEN') if (to.path == '/login') { //用户已经登陆了,不需要在到登陆页面 next('/') } else { //登陆后,存储用户的roles身份权限,然后筛选出符合条件的路由,添加到路由中 // !roles防止重复addRoutes添加路由,只有在第一次登陆才会添加路由 var roles = store.state.permission.roles && store.state.permission.roles.length > 0 if (!roles) { const routes = await store.dispatch('getAsyncRoutes', user.issuper) router.addRoutes([...routes]) next({ ...to, replace: true }) } else { next() } } } else { //登陆,注册页面不需要验证用户是否登陆 if (notAuthRouter.includes(to.path)) { next() } else { next('/login') } } }) router.afterEach(to => { ViewUI.LoadingBar.finish() }) export default router
store中的permission代码
import { routes, asyncRoutes } from '@/router/index'; //检查用户是否存在权限,根据路由的meta中的roles字段判断 function hasRoles(route, roles) { if (route.meta && route.meta.roles) { return route.meta.roles.includes(roles) } else { return true } } //筛选出符合权限的路由 function hasRouter(router, roles) { if (roles && roles.length > 0) { //用来存储符合条件的路由 let res = []; router.forEach(route => { //判断当前用户是否符合路由的权限 if (hasRoles(route, roles)) { //使用递归返回符合条件的子路由 if (route.children) { route.children = hasRouter(route.children, roles) } //符合权限就存储路由 res.push(route) } }) return res; } } const state = { //存储用户的权限,管理员admin,普通用户user roles: '', routes: routes // 用于配置页面导航等 }; const mutations = { SET_ROLES: (state, roles) => { state.roles = roles }, SET_ROUTES: (state, routes) => { state.routes = routes } } const actions = { /**根据角色获取路由配置 */ getAsyncRoutes({ commit }, roles) { commit('SET_ROLES', roles) var filterRoutes = hasRouter(asyncRoutes, roles) commit('SET_ROUTES', filterRoutes) return routes.concat(filterRoutes) } } export default { state, mutations, actions }
this.$router.options.routes获取不到addRoutes注入的路由解决办法
之前我们已经把符合权限的路由存储到了vuex中,可以获取vuex中的值
mounted() { const router = this.$router.options.routes; var menuRouter = this.get_menu; menuRouter = menuRouter.filter(item => { return !item.hidden && item.children && item.children.length > 0; }); this.routerList = router.concat(menuRouter); }
发表评论
侧栏公告
寄语
譬如朝露博客是一个分享前端知识的网站,联系方式11523518。
热评文章
标签列表
热门文章
友情链接