vue项目的后台管理系统之------动态权限路由

vue项目的后台管理系统之------动态权限路由

首先我们定义基本路由建立router .js,这里有个坑,开始的时候我把403,404页面放在这里,每次在刷新的时候都会进如到403页面,从而导致路由不能正常进如。

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router);
/* Layout */
import Layout from '../views/layout/Layout'
    let routers = [
        {path: '/login', component: () => import('@/views/login/index'), hidden: true},
        // {path: '/403', component: () => import('@/views/404'), hidden: true},
        {
            path: '',
            component: Layout,
            redirect: '/home',
            children: [{
                path: 'home',
                name: 'home',
                component: () => import('@/views/home/index'),
                meta: {title: '首页', icon: 'home'}
            }]
        },
        // {path: '*', redirect: '/403', hidden: true}
    ];

let router = new Router({
  mode: 'history', //后端支持可开
  // scrollBehavior: () => ({y: 0}),
  // routes: constantRouterMap
  routes: [...routers]
})

export default router;

现在是我们必不可少的vuex页面了。因为后台数据不对所以我这边只能按照某个特定的数据普判断了。

//菜单 路由权限
import {allowMenuList} from '../../api/roles' //后台返回的接口数据
let routes = [
  {},{},{}这里放置你需要的路由,
  
]

 const menu = {
    state: {
        routers:[]
    },
    mutations: {
        routers: (state, data) => {
            state.routers = data
        }
    },
    actions: {
        routers(store,data){ //处理需要的路由数据,因为我的只有两级我就没有封装方法了处理
            return new Promise((resolve,reject)=>{
                allowMenuList().then(res=>{
                    let arr = [];
                    routes.forEach((item,index)=>{
                         res.data.forEach((item1,index1)=>{
                             if(item.name == item1.name){
                                 item.children1 = [];
                                 item.children.forEach((item2,index2)=>{
                                     item1.childrenList.forEach((item3,index3)=>{
                                          if(item2.name == item3.name){
                                              item.children1.push(item2);
                                          }
                                     })
                                 })
                                 arr.push(item);
                             }
                         })
                    })
                    arr = arr.map((item,index)=>{
                        item.children = item.children1;
                        return item;
                    })
                    arr.unshift({
                        path: '',
                        component: ()=> import('@/views/layout/Layout'),
                        redirect: '/home',
                        children: [{
                            path: 'home',
                            name: 'home',
                            component: () => import('@/views/home/index'),
                            meta: {title: '首页', icon: 'home'}
                        }]
                    });
                    arr.push({path: '/login', component: () => import('@/views/login/index'), hidden: true});
                    store.commit('routers', arr);
                    resolve(arr)
                }).catch(err=>{
                    reject(err)
                })
            })
        },
    }
}

export default menu

现在到我们的登陆了,会用到我们的router.addRoutes();

//点击我们的登陆登陆成功触发vuex
 this.$store.dispatch('routers').then((res)=>{
                      this.$router.addRoutes([...res,{path: '/403', component: () => import('@/views/404'), hidden: true},{path: '*', redirect: '/403', hidden: true}]);
                      this.$router.options.routes = res;//这个必须要有,不然不成功
                      this.loading = false;
                      this.$router.push({path: '/home'})
                  })

到这里动态路由已经成功了。当然在你进如页面刷新会不行的除非每次刷新都退出登陆页面。这不实际。SO我们再次用到router.beforeEach();在路由跳转前做些认证

import router from './router'
import store from './store'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
import { Message } from 'element-ui'
import { getToken } from '@/utils/auth' // 验权

const whiteList = ['/login'] // 不重定向白名单
router.beforeEach((to, from, next) => {
  NProgress.start()
  if (getToken()) {//是不是登陆状态
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done() 
    } else {
      if (store.getters.roles.length === 0) {
        store.dispatch('GetInfo').then(res => { // 拉取用户信息
                store.dispatch('routers').then((res1)=>{//触发vuex
                    router.addRoutes([...res1,{path: '/403', component: () => import('@/views/404'), hidden: true},{path: '*', redirect: '/403', hidden: true}]);
                    router.options.routes = res1;
                    next({...to,replace:true});
                }).catch(err=>{
                    store.dispatch('FedLogOut').then(() => {
                        Message.error(err || 'Verification failed, please login again')
                        next({ path: '/' })
                    })
                })
            next();
        }).catch((err) => {
          store.dispatch('FedLogOut').then(() => {
            Message.error(err || 'Verification failed, please login again')
            next({ path: '/' })
          })
        })
      } else {
        next()
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next('/login')
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done() // 结束Progress
})

到这算是完成了。

你可能感兴趣的:(vue项目的后台管理系统之------动态权限路由)