权限控制的思路:

      在router文件夹中的index.js文件中有一份路由表,表示每个路由的可访问权限.用户登录后,通过token获取用户的role,动态根据用户的role算出有权限的路由,通过router.addRoutes动态挂载路由.

      每一个后台的请求不管是 get 还是 post 都会让前端在请求 header里面携带用户的 token,后端会根据该 token 来验证用户是否有权限执行该操作。若没有权限则抛出一个对应的状态码,前端检测到该状态码,做出相对应的操作。

具体实现

  1. 创建vue实例将vue-router挂载,此时vue-router挂载一些登录或者不用权限的公用的页面
  2. 用户登录后,获取role,,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表
  3. 调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由
  4. 使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件

先编一个路由表

// router.js
 import Vue from 'vue';
 import Router from 'vue-router';import Login from '../views/login/';
 const dashboard = resolve => require(['../views/dashboard/index'], resolve);
 //使用了vue-routerd的[Lazy Loading Routes
 ](https://router.vuejs.org/en/advanced/lazy-loading.html)//所有权限通用路由表 
 //如首页和登录页和一些不用权限的公用页面
 export const constantRouterMap = [
   { path: '/login', component: Login },
   {
     path: '/',
     component: Layout,
     redirect: '/dashboard',
     name: '首页',
     children: [{ path: 'dashboard', component: dashboard }]
   },
 ]//实例化vue的时候只挂载constantRouter
 export default new Router({
   routes: constantRouterMap
 });//异步挂载的路由
 //动态需要根据权限加载的路由表 
 export const asyncRouterMap = [
   {
     path: '/permission',
     component: Layout,
     name: '权限测试',
     meta: { role: ['admin','super_editor'] }, //页面需要的权限
     children: [
     { 
       path: 'index',
       component: Permission,
       name: '权限测试页',
       meta: { role: ['admin','super_editor'] }  //页面需要的权限
     }]
   },
   { path: '*', redirect: '/404', hidden: true }
 ];通过meta标签来标示页面访问的权限. 如meta:{role: ['admin','super_editor'] }
注意:404页面一定要最后加载,如果放在constantRouterMap一同声明404,后面的页面都会被拦截到404页面
main.js
// main.js
 router.beforeEach((to, from, next) => {
   if (store.getters.token) { // 判断是否有token
     if (to.path === '/login') {
       next({ path: '/' });
     } else {
       if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
         store.dispatch('GetInfo').then(res => { // 拉取info
           const 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'); // 否则全部重定向到登录页
     }
   }
 }); 
store/permission.js
// store/permission.js
 import { 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;

通过用户的权限和之前router.j里asyncRouterMap每个页面所需权限做匹配,左后返回该用户能访问的那些路由.