老闆讓我十分鐘上手開發vue-element-admin

relsoul發表於2018-01-04

大體走向

參考資料:

  1. vue-element官方介紹教程

首先這裡就不說vue和vuex之類的了 有興趣的可以去官方文件瞭解。這裡根據走向大概說說

登入

首先是登入頁也就是/login 那麼我們找到對應的登入頁面layout也就是 src/views/login/index.vue 找到這個頁面後,不急著看邏輯,繼續看路由配置,路由配置放在了src/router/index.js

路由配置

在路由配置裡暴露了兩個常量 一個是 constantRouterMap 另外一個是 asyncRouterMap 這裡先說說constantRouterMap。 vue-element的許可權驗證大概是

  1. 預設大家都能訪問的頁面,不需要登入啊許可權啊 啥都不需要 遊客訪問的頁面抽離定義為 constantRouterMap
  2. 需要登入或者需要許可權的頁面路由抽離為 asyncRouterMap

根據後臺獲取到使用者role的不同來動態載入asyncRouterMap中meta.role的許可權對應的頁面

點選登入後做的事情

還是回到剛剛的login頁面,點選登入以後就直接進入dashboard頁面了, 左側的側邊欄也有導航列表了。 這裡引出兩個疑問

  1. 根據路由配置說的 動態載入對應的許可權路由 那麼側邊欄那麼多路由 肯定不能寫死吧?
  2. 我點選登入後 那些登入流程怎麼走的?使用者許可權存在哪裡?token在哪裡?

側邊欄的動態渲染

根據問題1來回答 首先我們找到layout也就是src/views/layout/Layout.vue, 因為在路由配置檔案我們看見asyncRouterMap中好多元件的父元件都是Layout 在Layout中我們就可以看到有個元件sidebar

ok繼續找sidebar這個元件 src/views/layout/components/Sidebar/index.vue,發現這裡就是渲染側邊欄的,然後找到渲染的變數是permission_routers 這個變數是存在vuex裡面的 所以咋們去vuex裡面找找看 src/store/modules/permission.js

路由的動態載入

src/store/modules/permission.js 這個檔案裡面有個actions

   GenerateRoutes({ commit }, data) {
      return new Promise(resolve => {
        const { roles } = data
        let accessedRouters
        if (roles.indexOf('admin') >= 0) {
          accessedRouters = asyncRouterMap
        } else {
          accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
        }
        commit('SET_ROUTERS', accessedRouters)
        resolve()
      })
    }
複製程式碼

發現就是這一段程式碼更改了permission_routers,具體邏輯咋們不看 簡單解釋來說就是

    如果使用者的許可權是管理員
        把asyncRouterMap所有的路由頁面都渲染出來,畢竟管理員嘛 你懂得許可權汪。
    否則 
        我不是管理員但是也不是遊客就是一小市民 那麼我要去asyncRouterMap中找找我小市民能夠訪問哪些頁面。
複製程式碼

看完這段邏輯咋們就知道了這個路由是如何動態更改的了,等等,是不是忘了啥? 雖然我知道這個actions,但是。。。在哪呼叫的? 經過深思熟慮的著想,在花了0.1s後 就得出,既然是路由嘛 肯定是有個全域性的地方要做判斷的 所以得出結論就是 router.beforeEach, 一開始去找那個啥src/main.js,發現beforeEach被分離在src/permission.js 開啟這個檔案。一切疑問都解開了。

使用者許可權的獲取

說真的。。這個檔案好長。。都不想看了。。。。 下圖的程式碼這麼長 看個毛啊。。於是我簡單翻譯了下

router.beforeEach((to, from, next) => {
  NProgress.start() // start progress bar
  if (getToken()) { // 判斷是否有token
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done() // router在hash模式下 手動改變hash 重定向回來 不會觸發afterEach 暫時hack方案 ps:history模式下無問題,可刪除該行!
    } else {
      if (store.getters.roles.length === 0) { // 判斷當前使用者是否已拉取完user_info資訊
        store.dispatch('GetUserInfo').then(res => { // 拉取user_info
          const roles = res.data.role
          store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可訪問的路由表
            router.addRoutes(store.getters.addRouters) // 動態新增可訪問路由表
            next({ ...to, replace: true }) // hack方法 確保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
          })
        }).catch(() => {
          store.dispatch('FedLogOut').then(() => {
            Message.error('Verification failed, please login again')
            next({ path: '/login' })
          })
        })
      } else {
        // 沒有動態改變許可權的需求可直接next() 刪除下方許可權判斷 ↓
        if (hasPermission(store.getters.roles, to.meta.role)) {
          next()//
        } else {
          next({ path: '/401', query: { noGoBack: true }})
          NProgress.done() // router在hash模式下 手動改變hash 重定向回來 不會觸發afterEach 暫時hack方案 ps:history模式下無問題,可刪除該行!
        }
        // 可刪 ↑
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) { // 在免登入白名單,直接進入
      next()
    } else {
      next('/login') // 否則全部重定向到登入頁
      NProgress.done() // router在hash模式下 手動改變hash 重定向回來 不會觸發afterEach 暫時hack方案 ps:history模式下無問題,可刪除該行!
    }
  }
})
複製程式碼

翻譯成♂人話的版本。。。

    每次更改頁面路由
        你有沒有token啊?
            有的
                好的,你的許可權是預設的許可權0麼?
                    是的。。我就是一遊客
                        系統獲取我的資訊..拿到許可權值,動態載入路由(GenerateRoutes)...通行...
                    不是。。我是許可權汪(admin)
                        等等..我看看作者有沒有把你降級
                            沒有
                                好了。。你還是許可權汪 請進
                            有
                                滾吧,你已經不是許可權汪了,作者已經把你寫成戰鬥力只有5的渣渣了
            沒有
                沒有還敢闖這裡?滾去關口(/login)
複製程式碼

沒錯,就這麼簡單。整個許可權驗證流程就完整了。剩下的就是讀讀文件啊,看看如何使用元件之類的了。先寫這麼多 後續繼續看的時候有啥心得再寫新文章。要不然怎麼凸顯我文章數量麼

相關文章