前言
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)推出邱縣免費(fèi)做網(wǎng)站回饋大家。
最近一直在忙著一個(gè)用vue來(lái)做的權(quán)限管理的項(xiàng)目,其實(shí)在此之前,我也研究過(guò)vue的權(quán)限如何實(shí)現(xiàn),并且也為之寫(xiě)過(guò)一篇博客,但當(dāng)真正應(yīng)用在項(xiàng)目中的時(shí)候,還是發(fā)現(xiàn)了許多問(wèn)題,所以此篇也會(huì)就著我在項(xiàng)目中遇到的一些問(wèn)題,拿出來(lái)和大家分享一下,當(dāng)然示例代碼還是我的github倉(cāng)庫(kù)中的ant-design-vue-ms (本地下載)。
權(quán)限問(wèn)題解決思路
對(duì)于一個(gè)前后端分離的項(xiàng)目而言,權(quán)限不再是僅僅靠后端來(lái)控制,后端只能控制接口的權(quán)限,前臺(tái)的頁(yè)面顯示還是需要我們來(lái)控制,針對(duì)vue的項(xiàng)目,首先我想的是當(dāng)權(quán)限不多,并且都是單個(gè)權(quán)限的情況下,我們完全沒(méi)有必要使用vue中提供的addRoutes的方法,可以使用動(dòng)態(tài)組件來(lái)做,即我們根據(jù)后端返回的角色,來(lái)細(xì)度控制動(dòng)態(tài)組件的顯示內(nèi)容,所謂動(dòng)態(tài)組件其實(shí)就是vue內(nèi)置提供的component組件
<component :is="currentComponent"/>
相信看到這里,熟悉的同學(xué)應(yīng)該已經(jīng)想起來(lái)了,這樣的話,我們就不需要用到vuex,以及路由配置等等復(fù)雜的問(wèn)題,單純靠后臺(tái)返回的角色名稱就能解決所有的問(wèn)題了,看到這里是不是覺(jué)得今天的內(nèi)容就這些了,別著急,下面還有“好看的”。
權(quán)限設(shè)置中的問(wèn)題
這樣雖然能解決一些簡(jiǎn)單權(quán)限的問(wèn)題,但是針對(duì)稍微復(fù)雜一些的權(quán)限應(yīng)用,就顯得有些力不從心了,當(dāng)角色過(guò)多,并且還包含了混合角色的權(quán)限的話,則會(huì)衍生出很多問(wèn)題,這里也是列舉我遇到的一些問(wèn)題,同學(xué)們可以細(xì)細(xì)推敲一下。
所以綜上所述,最終我還是選擇了傳統(tǒng)的addRoutes,那么肯定會(huì)有同學(xué)問(wèn)了,既然這個(gè)方案不行,那干嘛還要用呢。問(wèn)得好,其實(shí)動(dòng)態(tài)組件就是一種嘗試,只有知道錯(cuò)了,不滿足需求了,我們才能更知道為什么會(huì)去使用傳統(tǒng)的addRoutes的權(quán)限方案。
權(quán)限問(wèn)題解決方法
所以我們來(lái)看看addRoutes帶來(lái)的一些“好處”:
相信做過(guò)權(quán)限的同學(xué)對(duì)上面的內(nèi)容還是有一些心得的,然后我們按照該有的步驟一步一步來(lái),這些步驟在上面我的github中已經(jīng)有了,大家可以對(duì)照一下。
1、全局導(dǎo)航守衛(wèi)的設(shè)置,此處設(shè)置全局導(dǎo)航守衛(wèi),我覺(jué)得更多是為了數(shù)據(jù)持久化,大家都知道,vuex雖然非常好用,但是會(huì)有刷新丟失數(shù)據(jù)的情況,因此針對(duì)這種情況,我們使用導(dǎo)航守衛(wèi),每次刷新的時(shí)候,會(huì)重新請(qǐng)求后臺(tái)的接口來(lái)獲取角色信息。
if (store.getters.roles.length === 0) { store .dispatch('GetInfo') .then(res => { const roles = res.data.resultData && res.data.resultData.roles store.dispatch('GenerateRoutes', { roles }).then(() => { // 根據(jù)roles權(quán)限生成可訪問(wèn)的路由表 // 動(dòng)態(tài)添加可訪問(wèn)路由表 router.addRoutes(store.getters.addRouters) }) }) .catch(() => { store.dispatch('Logout').then(() => { next({ path: '/user/login', query: { redirect: to.fullPath } }) }) }) } else { next() }
這里代碼做了簡(jiǎn)化,主要給大家看下上面會(huì)有一個(gè)角色判斷長(zhǎng)度,主要是當(dāng)我們不刷新的情況,頁(yè)面角色信息不回丟失,因此我們也就沒(méi)有必要去請(qǐng)求后臺(tái)獲取角色信息了,來(lái)節(jié)省請(qǐng)求數(shù)量。
2. 通過(guò)上面的代碼可以看到,我們首先是請(qǐng)求的角色信息,然后請(qǐng)求了生成路由的GenerateRoutes的方法,方法是寫(xiě)在vuex中的action里面的,這部分的內(nèi)容因?yàn)榫W(wǎng)上有很多教程,其實(shí)主要?dú)w納一下,就是對(duì)路由進(jìn)行遞歸過(guò)濾,過(guò)濾出符合角色的路由,然后將靜態(tài)路由和過(guò)濾出來(lái)的動(dòng)態(tài)路由鏈接起來(lái)
const permission = { state: { routers: constRouterMap, addRouters: [] }, mutations: { SET_ROUTERS: (state, routers) => { state.addRouters = routers state.routers = constRouterMap.concat(routers) } }, actions: { GenerateRoutes({ commit }, data) { //略 } } }
3、設(shè)置我們的路由文件,這部分放到這里來(lái)說(shuō),主要因?yàn)檫@里還有個(gè)小坑,所以也是特地拿出來(lái)和大家分享一下
export const constRouterMap = [ { path: '/', redirect: '/index', component: BasicLayout, children: [ { path: '/index', name: 'index', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'), meta: { title: '儀表盤(pán)' } }, { path: '/home', name: 'home', component: () => import(/* webpackChunkName: "home" */ '@/views/Home.vue'), meta: { title: '表單頁(yè)' } }, { path: '/pattern', name: 'pattern', component: () => import(/* webpackChunkName: "pattern" */ '@/views/DesignPattern.vue') }, { path: '/map', name: 'map', component: () => import(/* webpackChunkName: "map" */ '@/views/DataMap.vue'), meta: { title: '地圖組件' } }, ] }, { path: '/user', redirect: '/login', component: UserLayout, children: [ { path: '/login', name: 'login', component: () => import(/* webpackChunkName: "login" */ '@/views/user/Login.vue') }, { path: '/register', name: 'register', component: () => import(/* webpackChunkName: "login" */ '@/views/user/Register.vue') } ] }, //需要注意這里,404的路由一定要寫(xiě)在靜態(tài)路由中 { path: '/404', component: () => import(/* webpackChunkName: "not_found" */ '@/views/NotFound.vue') } ] export const asyncRouterMap = [ { path: '/', redirect: '/index', component: BasicLayout, children: [ { path: '/controls', name: 'controls', component: () => import(/* webpackChunkName: "controls" */ '@/views/Controls.vue'), meta: { title: '權(quán)限設(shè)置', permission: ['admin'] } } ] }, //捕獲未定義的路由配置 { path: '*', redirect: '/404', hidden: true } ]
上面關(guān)于404頁(yè)面的定義順序非常重要,如果在靜態(tài)路由中定義了捕獲的路由path:"*",而在動(dòng)態(tài)路由中定義了404路由的話,則當(dāng)導(dǎo)航鉤子中判斷比較復(fù)雜的話,會(huì)出現(xiàn)一些意想不到的錯(cuò)誤,我就是當(dāng)時(shí)寫(xiě)反了順序,并且還在導(dǎo)航鉤子中做了一些復(fù)雜的面包屑的判斷,一旦刷新頁(yè)面的話,則會(huì)出現(xiàn)以下錯(cuò)誤
這種錯(cuò)誤的產(chǎn)生,可能是因?yàn)樗⑿聲r(shí),導(dǎo)航鉤子發(fā)現(xiàn)動(dòng)態(tài)添加進(jìn)來(lái)的路由找不到一直進(jìn)行獲取動(dòng)態(tài)路由的方法,導(dǎo)致最后調(diào)用棧溢出所導(dǎo)致,因此大家在使用的時(shí)候一定要非常小心。
4. 當(dāng)我們生成路由后,退出應(yīng)用的切換新的角色賬號(hào)進(jìn)行登錄時(shí),一定要記得的兩件事,第一就是清空vuex里面的角色信息,在不刷新的情況下,這些信息是不會(huì)丟失的,當(dāng)不同角色的賬號(hào)登錄時(shí),原來(lái)的角色依然存在,那么肯定會(huì)出現(xiàn)問(wèn)題,其次則是在跳轉(zhuǎn)會(huì)登錄頁(yè)的時(shí)候,需要設(shè)置刷新頁(yè)面的代碼
window.location.reload(); this.$router.push({name: 'login'});
先刷新以后再跳轉(zhuǎn)到登錄頁(yè),這個(gè)則是因?yàn)閍ddRoutes生成的路由在不刷新的情況下會(huì)一直存在,即使下個(gè)不同角色的賬號(hào)登錄時(shí),依然會(huì)拿之前存在的路由信息去進(jìn)行過(guò)濾,這樣過(guò)濾的結(jié)果必然是當(dāng)前角色的路由一個(gè)都不存在,因此生成的路由信息還是上個(gè)角色的路由,所以在完成了之前這些步驟時(shí),一定不要忘記了做這兩步,這樣也才是一個(gè)完整的權(quán)限解決方案
尾聲
以上也是我在項(xiàng)目中一些收貨吧,拿出來(lái)和大家分享,也是希望大家少走一些彎路,留心我們開(kāi)發(fā)中遇到的每個(gè)看似很小的問(wèn)題,其實(shí)往往是我們最后解決問(wèn)題的關(guān)鍵,不論是從動(dòng)態(tài)組件還是動(dòng)態(tài)路由,問(wèn)題的出現(xiàn)也是我們不斷去完善自己的過(guò)程。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)創(chuàng)新互聯(lián)的支持。
本文標(biāo)題:vue權(quán)限問(wèn)題的完美解決方案
當(dāng)前地址:http://jinyejixie.com/article30/ghddso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、外貿(mào)網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站改版、域名注冊(cè)、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)