vue后臺(tái)管理項(xiàng)目中配合vuex實(shí)現(xiàn)路由權(quán)限管理

大致以文件的形式進(jìn)行描述

1.router/index.js : 該文件定義了router, 分別為 constRoutes(靜態(tài)路由表,包括登錄航缀,404等) 和 asyncRouters (動(dòng)態(tài)路由表商架,需要進(jìn)行權(quán)限管理的都將定義在這里)

2.store/state.js : 在 state 中定義 asyncMenuList (動(dòng)態(tài)權(quán)限列表)和 rolesId (后臺(tái)返回權(quán)限碼 Array)

3.store/mutation.js : 在mutations中定義方法(修改state中的asyncMenuList 、 rolesId ):

        SET_MENU_LIST: (state, data) => {

            state.asyncMenuList = data

          }
          SET_ROLES_ID: (state, id) => {

            state.rolesId = id

          }

4.store/actions : 首先引入在router中定義的 asyncRoutes 芥玉,在登錄action中將后臺(tái)返回的rolesId存儲(chǔ)在vuex中蛇摸, 然后在 actions 中定義GetRoutes action:

GetRoutes ({commit}, data) {
     // 該 action 被外部調(diào)用,調(diào)用后灿巧,會(huì)更新vuex中存儲(chǔ)的asyncMenuList 
    return new Promise((resolve, reject) => {
      //判斷如果data為 ‘a(chǎn)ll’赶袄,則為超級(jí)管理員,否則調(diào)用menuFiltters方法對(duì)data進(jìn)行動(dòng)態(tài)路由匹配
      if (data === 'all') {
        //調(diào)用mutation中定義的 SET_MENU_LIST 方法抠藕,更新vuex中存儲(chǔ)的asyncMenuList 
        commit('SET_MENU_LIST', asyncRoutes)

      } else {

        let menuRoutes

        menuRoutes = menuFiltters(asyncRoutes, data)
        // 將匹配成功的路由更新到vuex中存儲(chǔ)的asyncMenuList中
        commit('SET_MENU_LIST', menuRoutes)

      }

      resolve()

    })

  }

5.store/actions : 在action外部定義函數(shù) menuFiltters 和 hasPermission

// 使用遞歸饿肺,匹配權(quán)限碼,返回符合權(quán)限碼的路由
  function menuFiltters (asyncRoutes, roles) {
    const res = []
    asyncRoutes.forEach(route => {
      const tmp = { ...route }
      if (hasPermission(roles, tmp)) {
        if (tmp.children) {
          tmp.children = menuFiltters(tmp.children, roles)
        }
        res.push(tmp)
     }
    })
    return res
  }

// 用 some 判斷 router 中的權(quán)限碼是否在數(shù)組 roles 中存在盾似,存在返回true敬辣,否則返回false
  function hasPermission (roles, router) {
    return roles.some(role => router.meta.roles.includes(Number(role)))
  }
    

6.permission.js : 定義路由守衛(wèi),調(diào)用 actions 中的 GerRoutes , 匹配動(dòng)態(tài)權(quán)限路由零院,代碼如下

import router from './router'
import store from './store'
import { getToken, getUuid, getUserName, getRoleIDs, removeToken, removeUserName, removeRoleIDs } from '@/utils/auth'
import { asyncRoutes } from '@/router'

const whiteList = ['/login']

router.beforeEach((to, from, next) => {
  // 每次加載路由判斷是否已經(jīng)獲取用戶信息 若未獲取用戶信息則跳轉(zhuǎn)到登錄
  if (getToken() && getUuid() && getUserName() && getRoleIDs()) {
    if (to.path === '/login') {
      removeToken()
      removeUserName()
      removeRoleIDs()
      store.commit('SET_USER_NAME', '')
      store.commit('SET_USER_TOKEN', '')
      store.commit('SET_ROLES_ID', '')
      store.commit('SET_MENU_LIST', [])
      next()
    } else {
      if (store.state.asyncMenuList.length === 0) {
        if (store.state.rolesId === 'all') {
          store.dispatch('GetRoutes', 'all').then(res => {
            router.addRoutes(asyncRoutes) // 異步加載路由
            next({...to, replace: true})
          })
        } else if (store.state.rolesId.length > 0 && store.state.rolesId !== 'all') {
          let menu
          if (typeof store.state.rolesId === 'string') {
            menu = JSON.parse(store.state.rolesId)
          } else {
            menu = store.state.rolesId
          }
          store.dispatch('GetRoutes', menu).then(() => {
            router.addRoutes(store.state.asyncMenuList) // 異步加載路由
            next({...to, replace: true})
          })
        } else {
          next()
        }
      } else {
        next()
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) { // 在免登錄白名單溉跃,直接進(jìn)入
      next()
    } else {
      next(`/login?redirect=${to.path}`) // 否則全部重定向到登錄頁
    }
  }
})

7.main.js : 引入permission : import './permission',使得每一次路由跳轉(zhuǎn)都會(huì)執(zhí)行路由守衛(wèi)
8.在頁面中獲得正確的動(dòng)態(tài)路由進(jìn)行渲染门粪,完成整個(gè)流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喊积,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子玄妈,更是在濱河造成了極大的恐慌乾吻,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拟蜻,死亡現(xiàn)場離奇詭異绎签,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)酝锅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門诡必,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搔扁,你說我怎么就攤上這事爸舒。” “怎么了稿蹲?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵扭勉,是天一觀的道長。 經(jīng)常有香客問我苛聘,道長涂炎,這世上最難降的妖魔是什么忠聚? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮唱捣,結(jié)果婚禮上两蟀,老公的妹妹穿的比我還像新娘。我一直安慰自己震缭,他們只是感情好赂毯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拣宰,像睡著了一般欢瞪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上徐裸,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天遣鼓,我揣著相機(jī)與錄音,去河邊找鬼重贺。 笑死骑祟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的气笙。 我是一名探鬼主播次企,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼潜圃!你這毒婦竟也來了缸棵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤谭期,失蹤者是張志新(化名)和其女友劉穎堵第,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體隧出,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡踏志,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胀瞪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片针余。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凄诞,靈堂內(nèi)的尸體忽然破棺而出圆雁,到底是詐尸還是另有隱情,我是刑警寧澤帆谍,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布伪朽,位于F島的核電站,受9級(jí)特大地震影響既忆,放射性物質(zhì)發(fā)生泄漏驱负。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一患雇、第九天 我趴在偏房一處隱蔽的房頂上張望跃脊。 院中可真熱鬧,春花似錦苛吱、人聲如沸酪术。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绘雁。三九已至,卻和暖如春援所,著一層夾襖步出監(jiān)牢的瞬間庐舟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工住拭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挪略,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓滔岳,卻偏偏與公主長得像杠娱,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谱煤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345