登录权限( 二 )


注意事项:这里有一个需要非常注意的地方就是 404 页面一定要最后加载,如果放在一同声明了404,后面的所以页面都会被拦截到404,详细的问题见
when you’ve got aroute for 404s does not work
main.js
// main.jsrouter.beforeEach((to, from, next) => {if (store.getters.token) { // 判断是否有tokenif (to.path === '/login') {next({ path: '/' });} else {if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息store.dispatch('GetInfo').then(res => { // 拉取infoconst roles = res.data.role;store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record})}).catch(err => {console.log(err);});} else {next() //当有用户权限的时候,说明所有可访问路由已生成 如访问没权限的全面会自动进入404页面}}} else {if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入next();} else {next('/login'); // 否则全部重定向到登录页}}});
这里的.也结合了上一章讲的一些登录逻辑代码 。
上面一张图就是在使用方法之前的权限判断,非常的繁琐,因为我是把所有的路由都挂在了上去,所有我要各种判断当前的用户是否有权限进入该页面,各种if/else的嵌套,维护起来相当的困难 。但现在有了之后就非常的方便,我只挂载了用户有权限进入的页面,没权限,路由自动帮我跳转的404,省去了不少的判断 。
这里还有一个小hack的地方,就是.之后的next()可能会失效,因为可能next()的时候路由并没有完全add完成,好在查阅文档发现
next(’/’) or next({ path: ‘/’ }):to a. Thewill beand a new one will be .
这样我们就可以简单的通过next(to)巧妙的避开之前的那个问题了 。这行代码重新进入.这个钩子,这时候再通过next()来释放钩子,就能确保所有的路由都已经挂在完成了 。
store/.js
就来就讲一讲
// store/permission.jsimport { asyncRouterMap, constantRouterMap } from 'src/router';function hasPermission(roles, route) {if (route.meta && route.meta.role) {return roles.some(role => route.meta.role.indexOf(role) >= 0)} else {return true}}const permission = {state: {routers: constantRouterMap,addRouters: []},mutations: {SET_ROUTERS: (state, routers) => {state.addRouters = routers;state.routers = constantRouterMap.concat(routers);}},actions: {GenerateRoutes({ commit }, data) {return new Promise(resolve => {const { roles } = data;const accessedRouters = asyncRouterMap.filter(v => {if (roles.indexOf('admin') >= 0) return true;if (hasPermission(roles, v)) {if (v.children && v.children.length > 0) {v.children = v.children.filter(child => {if (hasPermission(roles, child)) {return child}return false;});return v} else {return v}}return false;});commit('SET_ROUTERS', accessedRouters);resolve();})}}};export default permission;
这里的代码说白了就是干了一件事,通过用户的权限和之前在.js里面的每一个页面所需要的权限做匹配,最后返回一个该用户能够访问路由有哪些 。
侧边栏
最后一个涉及到权限的地方就是侧边栏,不过在前面的基础上已经很方便就能实现动态显示侧边栏了 。这里侧边栏基于-ui的来实现的 。
代码有点多不贴详细的代码了,有兴趣的可以直接去上看地址,或者直接看关于侧边栏的文档 。
说白了就是遍历之前算出来的,通过vuex拿到之后动态v-for渲染而已 。不过这里因为有一些业务需求所以加了很多判断
比如我们在定义路由的时候会加很多参数