流程思路
通用路由+路由表-->后端返回路由權限數據
數據與路由表相互映射 --> 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
})