首先我们定义基本路由建立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
})
到这算是完成了。