流程思路
通用路由+路由表-->后端返回路由权限数据
数据与路由表相互映射 --> addRoutes
addRoutes --> 全局路由拦截非权限内路由地址
f5刷新页面重新请求路由表
直接上代码
++router/index.js++
import Vue from 'vue'
import Router from 'vue-router'
//挂载到vue上
Vue.use(Router)
// 通用路由
export const constantRouterMap = [
{ path: '/login', component: () => import('@/views/login/index'), hidden: true },
{ path: '/404', component: () => import('@/views/404'), hidden: true },
{
path: '',
component: Layout,
redirect: 'dashboard',
children: [{
path: 'dashboard',
component: () => import('@/views/dashboard/index'),
name: 'dashboard',
meta: { title: '首页', icon: 'dashboard' }
}]
}
]
export default new Router({
// mode: 'history', //后端支持可开
scrollBehavior: () => ({ y: 0 }), //切换路由时滚动到顶部
routes: constantRouterMap //默认使用通用路由
})
//路由表,用于跟后端返回数据进行映射
//component属性的值为import进来的模块,如果不这样得做二次映射
export const newRouters = {
"routes": [
{
"path": "/user",
"component": Layout,
"redirect": "/user/userList",
"name": "User",
"meta": { "title": "用户系统", "icon": "user" },
"alwaysShow": true,
"children": [
{
"path": "userList",
"name": "UserList",
"component": () => import('@/views/UserList/index'),
"meta": { "title": "用户列表", "icon": "user" }
}
]
},
{
"path": "/webManager",
"component": Layout,
"redirect": "/webManager/home",
"name": "WebManager",
"meta": { "title": "网站管理", "icon": "money" },
"alwaysShow": true,
"children": [
{
"path": "home",
"name": "Home",
"component": () => import('@/views/WebManager/Home'),
"meta": { "title": "网站首页管理", "icon": "money" }
},
{
"path": "banner",
"name": "Banner",
"component": () => import('@/views/WebManager/Banner'),
"meta": { "title": "banner管理", "icon": "money", "parents": [ { "meta": { "title": "网站首页管理" }, "path": "/webManager/home" } ] },
"hidden": true
},
{
"path": "news",
"name": "News",
"component": () => import('@/views/WebManager/News'),
"meta": { "title": "资讯管理", "icon": "money", "parents": [ { "meta": { "title": "网站首页管理" }, "path": "/webManager/home" } ] },
"hidden": true
}
]
},
{ "path": "*", "redirect": "/404", "hidden": true }
]
}
++store/modules/user.js++
// 请求权限(路由)数据接口
import { newRoutersOnline } from '@/api/login'
import router, { newRouters } from '@/router/index'
// 路由映射函数
function recursionRouters(userRouter = [], newRouters = []) {
let addRouter = []
userRouter.forEach((userRouterItem, index) => {
newRouters.forEach((newRoutersItem, index) => {
if (newRoutersItem.path === userRouterItem.path) {
const item = newRoutersItem
if (userRouterItem.children) {
const children = recursionRouters(userRouterItem.children, newRoutersItem.children)
if (children.length) {
item.children = children
}
}
addRouter.push(item)
}
})
})
return addRouter
}
const user = {
state: {
routes: []
},
mutations: {
SET_ROUTES: (state, roles) => {
state.routes = roles
}
},
actions: {
SetRoutes({ commit, state }) {
return new Promise((resolve, reject) => {
newRoutersOnline().then(res => {
const newRoutes = recursionRouters(res.data, newRouters.routes)
commit('SET_ROUTES', [...router.options.routes, ...newRoutes])
resolve(newRoutes)
}).catch(error => {
reject(error)
})
})
},
}
++permission.js++//全局路由拦截配置文件
++utils/auth++
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)
}
import router from './router'
import store from './store'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
import { getToken } from '@/utils/auth' // 验权
const whiteList = ['/login', '/404'] // 不重定向白名单
router.beforeEach((to, from, next) => {
if (getToken()) {
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else {
//如果在登录状态,但是路由表丢失的情况下,调用store的请求路由表(适用于刷新页面后丢失store数据)
if (store.getters.routes.length === 0) {
store.dispatch('SetRoutes').then(res => {
//addRoutes应该不用解释了吧。。。
router.addRoutes(res)
next({ ...to, replace: true })
}).catch((err) => {
store.dispatch('FedLogOut').then(() => {
Message.error(err || '登陆失效,请重新登陆')
next({ path: '/' })
})
})
} else {
next()
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
NProgress.done()
}
}
}
router.afterEach(() => {
NProgress.done() // 结束Progress
})