本文的做法是為了解決在PC端管理系統(tǒng)中,不同角色登錄時(shí)候動(dòng)態(tài)加載對應(yīng)的路由表來達(dá)到路由權(quán)限的控制
方案1:路由跳轉(zhuǎn)時(shí),添加權(quán)限判斷鉤子,如果用戶前往的頁面不在權(quán)限列表內(nèi),則禁止跳轉(zhuǎn),這樣寫雖然也可以達(dá)到目的,但一旦系統(tǒng)角色多,這部分就會(huì)顯得繁瑣,難以維護(hù)
方案2:本地只存儲基本路由,如錯(cuò)誤處理頁面、無權(quán)限控制頁面等,而權(quán)限路由則根據(jù)用戶的token從服務(wù)器獲取,服務(wù)器根據(jù)用戶的權(quán)限下發(fā)相應(yīng)的路由數(shù)據(jù),客戶端利用這些數(shù)據(jù)進(jìn)行路由的動(dòng)態(tài)生成和添加
本文的做法跟方案2思路一樣,唯一不同的是路由表不是從服務(wù)端獲取,而是在項(xiàng)目文件中新建文件來保存
本文先假設(shè)系統(tǒng)中有2種角色-管理員和普通用戶
他們對應(yīng)的路由表如下:
adminRoutersTable.js:
export const adminRoutersTable=[
{ path: '/adminPage1',name: 'adminPage1', component: () => import('@/views/AdminUser/adminPage1')},
{ path: '/adminPage2',name: 'adminPage2', component: () => import('@/views/AdminUser/adminPage2') },
{ path: '/normalPage3',name: 'normalPage3', component: () => import('@/views/NormalUser/normalPage3'),auth:{userType:'admin'}},
{ path: '*',name: '404', component: () => import('@/views/error/404') }
]
normalRoutersTable.js:
export const normalRoutersTable=[
{ path: '/normalPage1',name: 'normalPage1', component: () => import('@/views/NormalUser/normalPage1') },
{ path: '/normalPage2',name: 'normalPage2', component: () => import('@/views/NormalUser/normalPage2') },
{ path: '/normalPage3',name: 'normalPage3', component: () => import('@/views/NormalUser/normalPage3'),auth:{userType:'normal'}},
{ path: '*',name: '404', component: () => import('@/views/error/404') }
]
系統(tǒng)初始路由配置
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{ path: '/',name: 'HelloWorld', component: () => import('@/components/HelloWorld') },
{ path: '/login',name: 'login', component: () => import('@/views/login/login') },
]
})
需要特別注意的,如果404頁面為靜態(tài)路由,那么第一次進(jìn)入頁面時(shí),這時(shí)動(dòng)態(tài)路由還未加載,找不到路由地址會(huì)默認(rèn)跳轉(zhuǎn)到404錯(cuò)誤頁,體驗(yàn)很差,所以404路由先不寫入路由規(guī)則中,和動(dòng)態(tài)路由一起加載。
為解決瀏覽器刷新路由重置的問題,拿到token后要將其保存到sessionStorage或cookie中,根組件的created鉤子負(fù)責(zé)檢查本地是否已有token,如果有則無需登錄直接用該token獲取權(quán)限并初始化,如果token有效且當(dāng)前路由有權(quán)訪問,將加載路由組件并正確展現(xiàn);若當(dāng)前路由無權(quán)訪問將按路由設(shè)置跳轉(zhuǎn)404;如果token失效,后端應(yīng)返回4xx狀態(tài)碼,前端統(tǒng)一為axios實(shí)例添加錯(cuò)誤攔截器,遇到4xx狀態(tài)碼執(zhí)行退出操作,清除sessionStorage數(shù)據(jù)并跳轉(zhuǎn)到登錄頁,讓用戶重新登錄。
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import Cookies from 'js-cookie'
Vue.config.productionTip = false
import {adminRoutersTable} from '@/router/adminRoutersTable';//管理員路由表
import {normalRoutersTable} from '@/router/normalRoutersTable';//普通用戶路由表
new Vue({
el: '#app',
router,
components: {App},
template: '<App/>',
created() {
//一旦刷新瀏覽器就會(huì)執(zhí)行這里
console.log('刷新')
//下面這段代碼在實(shí)際開發(fā)中應(yīng)該封裝起來,因?yàn)樵诘顷懙臅r(shí)候也會(huì)用到
//登陸成功則在cookie中設(shè)置對應(yīng)的token值,然后執(zhí)行類似下面的代碼
//注意:這里的this.$router.addRoutes是vue-router2.2版本后才有的方法
if(Cookies.get('user_token')){
switch (Cookies.get('user_token')){
case 'admin':
this.$router.addRoutes(adminRoutersTable);
break;
case 'normal':
this.$router.addRoutes(normalRoutersTable);
break
default:
break;
}
}else{
this.$router.repalce('/login')
}
},
mounted() { /* 在這發(fā)起后端請求,拿回?cái)?shù)據(jù),配合路由鉤子做一些事情 */
}
})
還有一種情況需要注意:管理員與普通用戶共同擁有某個(gè)路由界面,但因?yàn)椴僮鳈?quán)限不同,可能界面上某個(gè)操作按鈕對于管理員是可見的,但對于普通用戶來說是不可見的。
解決方式:在那個(gè)路由記錄中添加一個(gè)自定義的auth字段來判斷