Vue保持用户登录及权限控制
vue-router-power-demo
核心內(nèi)容有兩點(diǎn): 一是保持用戶登錄狀態(tài),二是根據(jù)登錄用戶的角色動態(tài)掛在路由
使用vuex保持用戶登錄
動態(tài)掛在路由
src項(xiàng)目結(jié)構(gòu)
src │ App.vue │ main.js │ permission.js // vue router 守衛(wèi)導(dǎo)航,對token和role進(jìn)行判斷 ├─api // 統(tǒng)一管理前端與服務(wù)器之間的api接口 ├─layout // 主視圖的結(jié)構(gòu)管理,包括header,side-bar,main-body等 │ │ index.vue │ └─components │ ├─header │ │ index.vue │ └─sidebar │ index.vue │ side-item.vue // side-bar菜單動態(tài)渲染的核心組件 ├─mock // 前端模擬服務(wù)器獲取數(shù)據(jù),modules下的文件名和api接口一一對應(yīng) │ │ index.js │ └─modules │ getuserinfo.js │ login.js │ logout.js ├─router // 路由表,本身只需要一個index,為了結(jié)構(gòu)分離了兩個路由表 │ asyncRoutes.js // 需要動態(tài)掛載的路由表 │ constantRoutes.js // 常規(guī)路由表,通常為 login、404等一些不需要權(quán)限的路由表 │ index.js ├─store // 加載 store 模塊和 getters │ │ getters.js // 全局getters │ │ index.js │ └─modules // 模塊形式的store │ permission.js │ user.js ├─style │ index.scss ├─utils │ request.js // 封裝了axios,這里只是簡單封裝,但實(shí)際項(xiàng)目中肯定有各種需求 └─views // 各個頁面內(nèi)容├─document│ index.vue├─error-page│ 404.vue├─login│ index.vue├─page1│ index.vue├─page2│ index.vue└─permissionpage.vuesuper.vueuser.vue敲黑板,劃重點(diǎn)
permission.js
放置全局導(dǎo)航守衛(wèi),和文件名含義一樣,對用戶的跳轉(zhuǎn)行為進(jìn)行許可判斷,主要是利用vuex.store中的token和role進(jìn)行判斷,并完成路由的動態(tài)加載行為
store/modules/user.js
用戶的全局狀態(tài),最關(guān)鍵的兩個變量,token 和 role 。
token的默認(rèn)值可以用cookies.get('token')獲取,因?yàn)楫?dāng)頁面刷新時,vuex.store中的所有狀態(tài)都會重置,本身就需要判斷和從cookie中獲取,這樣寫省了一次判斷,而且更為便捷。
actions的內(nèi)容分發(fā),主要有三個,login獲取后臺token并保存,getUserInfo獲取用戶信息并保存,logout清除本地的token和role等信息
store/modules/permission.js
用于儲存全局路由表,有兩個作用,一是獲取需要動態(tài)掛載的路由表,二是用于側(cè)邊欄的導(dǎo)航渲染。
actions的主要內(nèi)容時用role對asyncRoutes路由表進(jìn)行篩選
router/constantRoutes.js 和 router/asyncRoutes.js
constantRoutes.js asyncRoutes.js這兩個路由表很簡單,本來就是和index.js一起配置的,但是為了清晰邏輯和結(jié)構(gòu)把這兩個表分離了出來。constantRoutes是默認(rèn)加載路由,asyncRoutes是需要使用role進(jìn)行篩選的路由,路由表的結(jié)構(gòu)及配置是需要配合store/modules/permission.js一起使用。
這里使用的篩選邏輯:對每個route判斷是否配置了meta.roles,如果沒有,則表示該route全局可用,如果有,再查找meta.roles中是否有role的值,如果有表示該用戶有使用這個route的權(quán)限。
最后很重要的一點(diǎn),asyncRoutes路由表的最后需要配置{ path: '*', hidden: true, redirect: '/404' },并且只能配置在最后,用來跳轉(zhuǎn)非合法的url
不在重點(diǎn)中的重點(diǎn)
這個說法有點(diǎn)矛盾,之所以說不在重點(diǎn)中,是因?yàn)樯厦娴膉s中已經(jīng)完成了用戶的登錄及頁面權(quán)限的分配。
但是,我要說但是了,網(wǎng)頁是需要導(dǎo)航頁來引導(dǎo)用戶的,如果將所有連接都放入導(dǎo)航頁,那么沒有權(quán)限的用戶點(diǎn)擊會跳轉(zhuǎn)到404頁,這在用戶體驗(yàn)上不好,那么就需要在渲染導(dǎo)航頁的時候?qū)ole進(jìn)行判斷。導(dǎo)航頁少的時候還不麻煩,導(dǎo)航頁一多就會顯得十分繁重,而且不易維護(hù)。所以使用路由表動態(tài)的渲染出導(dǎo)航。
在store/modules/permission.js的state中有個routes存儲了該用戶完整的權(quán)限路由表,導(dǎo)航菜單就是循環(huán)渲染這個路由表,但是該路由表中有許多路由時不需要在導(dǎo)航頁中出現(xiàn)的,比如login,404等。這個時候就需要用到路由表中的hidden設(shè)置了,渲染的時候通過hidden來判斷是否將該路由渲染到導(dǎo)航菜單中。
官方的標(biāo)準(zhǔn)路由表中是沒有hidden這個配置的,這個選項(xiàng)其實(shí)應(yīng)該是寫在meta中的,只是可能為了方便寫在了最外層,網(wǎng)上能找到的很多路由權(quán)限實(shí)列都是這樣寫的。所以如果有多個導(dǎo)航菜單并存的情況下,hidden不妨也可以改寫成showOnTop、showOnSide,渲染的時候使用對應(yīng)的選項(xiàng)進(jìn)行判斷即可。
既然導(dǎo)航菜單是用路由表渲染的,那么路由表的結(jié)構(gòu)和順序就顯得十分重要的,這和渲染出來的導(dǎo)航菜單順序及結(jié)構(gòu)是一直的,復(fù)雜的導(dǎo)航菜單通常都有二級菜單和三級菜單,這用到了組件的遞歸,因?yàn)楸容^復(fù)雜,所以這個demo只做了簡單的一級導(dǎo)航,目的是為了清晰的展示登錄和頁面權(quán)限管理
DEMO預(yù)覽地址
DEMO預(yù)覽地址
DEMO項(xiàng)目地址
在GitHub上配置的靜態(tài)文件的問題記錄:在GitHub的靜態(tài)頁面上,頁面內(nèi)部跳轉(zhuǎn)沒有問題,刷新后就找不到頁面了。
根本原因在于demo展示的實(shí)際地址是https://cliff-rhine.github.io/vue-router-power-demo/,而vue的路由配置是在根目錄上的,導(dǎo)致在頁面內(nèi)容跳轉(zhuǎn)url之后,瀏覽器的url地址已經(jīng)變成根目錄依賴,而非/vue-router-power-demo/。所以在刷新頁面時找不到文件。vue-router的url跳轉(zhuǎn)機(jī)制實(shí)際上是html5的history.pushState和history.replaceState。
項(xiàng)目在本地配置沒有問題,可以正常刷新頁面
TODO
- 頁面按鈕權(quán)限管理
總結(jié)
以上是生活随笔為你收集整理的Vue保持用户登录及权限控制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: element-ui Notificat
- 下一篇: html5倒计时秒杀怎么做,vue 设