vue动态添加路由(路由权限)

4,286 阅读3分钟
  • 后台管理系统,不同等级的用户会有不同的权限,看到的页面也会不同,这个时候就会用到动态添加路由,主要用到如下语句。
router.options.routes = routes;//router.options.routes 不是响应式的
router.addRoutes(routes)
  • 下面是做权限系统时,个人做法,如有不妥,忘指教。

router/index.js

import Vue from 'vue'
import Router from 'vue-router'

import newLogin from '@/components/Login/login'//  登录
import Index from '@/components/Index/index'//  主页

const Home = () => import('@/components/Home/index.vue')//home

// 解决同个路由重复点击报错
const originalPush = Router.prototype.push;
Router.prototype.push = function push(location) {
  return originalPush.call(this,location)
}

Vue.use(Router)

//不需要登录即可看到的路由页面
const constantRoutes = [
  {
    path: '/login',
    name: 'login',
    component: newLogin,
    meta:{
      isLogin:false,
      title:'***'
    }
  },
  {
    path: '/',
    component: Index,
    redirect: '/home',
    children: [
      {
        path: '/home',
        name:'home',
        component: Home,
        meta:{
          isLogin:false,
          keepAlive: true,
          title:'***'
        }
      },
    ]
  }
]
//创建路由
const createRouter = () => new Router({
  routes: constantRoutes
})
const router = createRouter()

//写一个重置路由的方法,切换用户后,或者退出时清除动态加载的路由
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // 新路由实例matcer,赋值给旧路由实例的matcher,(相当于replaceRouter)
}

export default router

在登录后获取后端返回的用户可用权限,当然这里需要和后端人员商定一个前后端一致的权限表。拿到后端返回的此用户的权限,根据权限表去对比,从而动态添加此用户权限路由。
我是在store.js文件里获取的用户权限,直接赋上代码。

  • 与后端商定的权限表,每个路由的permission保证前后端一致

sideList.js 是侧边栏亦是路由表,isPermission为true展示到侧边栏,isPermission在store.js设定

allrouter.js是全部事先定义好的的路由页面

store.js

import Vuex from 'vuex';
import Vue from 'vue'
import sideList from '@/router/sideList.js'
import router from '@/router/index.js'
import allRouter from '@/router/allRouter'
import axios from 'axios'
import { api } from '@/assets/config/interface_api.js'
import { Message } from 'element-ui';
import { setCookie, getCookie, delCookie, delAllCookie } from '@/assets/js/cookie.js'
Vue.use(Vuex);
const state = {  //要设置的全局访问的state对象
  sideList:sideList
};
const getters = {
  getSideList(state) {
    return state.sideList
  }
}
const mutations = {
}
const actions = {
  permissionInit({ commit, state }, obj) {
    return new Promise(function (resolve, reject) {
      //获取用户被禁用权限
      axios.get(api.BASEURL + api.getPermissions)
        .then(function (res) {
          let data = res.data;
          if(data && data.errno == 0){
            var permissionPHP = data.rst.permissions;
            var sideArr = [].concat(sideList);
            var addRoutes = [];
            sideArr.forEach((item,index) =>{
              if(permissionPHP.indexOf(item.permission) != -1){
                //权限存在
                item.isPermission = true;
                item.groupList.forEach((smallItem)=>{
                  if(permissionPHP.indexOf(smallItem.permission) != -1){
                    //权限存在,isPermission为true展示到侧边栏
                    smallItem.isPermission = true;
                    //拼接要动态添加的路由
                    addRoutes.push({
                      path:smallItem.path,
                      name:smallItem.component,
                      component:allRouter[smallItem.component],
                      meta:{
                        title:smallItem.name
                      }})
                  }
                })
              }
            })
            if(addRoutes.length == 0){
              Message({
                type: 'warning',
                message: '对不起,您暂无权限查看本系统!'
              });
              return;
            }
            
            //state.sideList为最终确定用户权限所展示的侧边栏
            state.sideList = sideArr;
            
            //拼接(routes)要添加的路由
            var routes = [
              {
                path: "*",
                component: allRouter.errorPage,
              },{
                path: '/',
                component: allRouter.Index,
                redirect:addRoutes[0].path,
                children: addRoutes
              }]
            router.options.routes = routes;//router.options.routes 不是响应式的
            router.addRoutes(routes)
            resolve(true);
          }else{
            // Message({
            //   type: 'warning',
            //   message: data.err
            // });
          }
        }).catch(()=>{
          Message({
            type: 'warning',
            message: '系统错误,请稍后重试!'
          });
        })
    });
  }
}
const store = new Vuex.Store({
  state,
  getters,
  mutations,
  actions
});
export default store;

main.js

// 权限控制------
store.dispatch('permissionInit').then((res)=>{
  console.log(res,'成功')
})
// 登录拦截
router.beforeEach((to, from, next) => {
  if (to.meta.title) {
    document.title = to.meta.title
  }
  if(to.path == '/login'){
    if(getCookie('role_id') && Boolean(getCookie('isLogin'))){
      //登录未过期
      next('/')
    }else{
      next();
    }
  }else{
    if(!getCookie('role_id') || !Boolean(getCookie('isLogin'))){
      // 登录过期
      next('/login')
    }else{
      next();
    }
  }
});

登录页面login.vue

 this.$axios({
        url: this.URL.BASEURL + this.URL.LOGIN,
        method: 'post',
        data:{
            phone:this.phone,
            type:1,
            code:this.code,
        }
    }).then((res) => {
        this.loading.close();
        var res=res.data;
        if(res&& res.errno == 0){//登录成后
            var data=res.rst;
            this.$cookieStore.setCookie('admin_id',data.id)
            this.$cookieStore.setCookie('isLogin',true)
            
            this.$store.dispatch('permissionInit').then((res)=>{
                let routeData = '';
                this.$router.push('/');
            })
            
        }else{
            
        }

退出登录,或者切换用户后,清除动态添加的路由,调用router/index.js里预留的方法resetRouter