天天看點

element ui的vue-element-admin背景內建方案

路由權限校驗

路由配置檔案 ​

​src/router/index.js​

​​,找到​

​asyncRoutes​

​​這個數組,在需要配置權限的路由上添加​

​meta​

​​屬性,​

​meta​

​​是一個對象,​

​meta​

​​對象上添加​

​roles​

​​屬性,​

​roles​

​​是一個數組,裡面可以放​

​admin​

​​、​

​editor​

​兩個角色。

export const asyncRoutes = [
  { path: '/book',
    component: Layout,
    redirect: '/book/create',
    meta: { title: '圖書管理', icon: 'documentation', roles: ['admin'] },
    children: [
      {
        path: '/book/create',
        component: () => import('@/views/book/create'),
        meta: { title: '上傳圖書', icon: 'edit', roles: ['admin'] },
      }
    ] 
  },
  { path: '*', redirect: '/404', hidden: true }
]      

浏覽器通路某個路由的時候,首先會進入一個全局的路由守衛 ​

​router.beforeEach​

​​,這部分代碼在​

​src/permission.js​

​檔案裡。以下步驟是路由守衛裡執行的一系列邏輯步驟:

router.beforeEach(async(to, from, next) => {
  // 啟動進度條
  NProgress.start()
 
  // 設定頁面title
  document.title = getPageTitle(to.meta.title)
 
  // 從cookie中擷取token
  const hasToken = getToken()
 
  // 判斷token是否存在
  // token存在
  if (hasToken) {
    // 判斷路由是否為 /login
    // 是 /login
    if (to.path === '/login') {
      // 路由重定向到 /
      next({ path: '/' })
      NProgress.done()
    } else {
      //  擷取使用者角色
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      // 如果角色存在則進行下一步
      if (hasRoles) {
        next()
      } else {
      // 如果角色不存在
        try {
          // 擷取角色
          const { roles } = await store.dispatch('user/getInfo')
 
          // 根據roles生成動态路由
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
 
          // 合并路由
          router.addRoutes(accessRoutes)
 
          // replace設定成true 為的是讓使用者登入進去之後點選浏覽器回退,會退到空白頁而不是登入頁
          next({ ...to, replace: true })
        } catch (error) {
          // 如果出現異常 把token清空 roles清空 cookie清空
          await store.dispatch('user/resetToken')
          // 列印錯誤
          Message.error(error || 'Has Error')
          // 重定向到login 并帶上上次通路的路由
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    /* 如果token不存在 */
    // 如果路由存在白名單裡
    if (whiteList.indexOf(to.path) !== -1) {
      // 那就通路此路由
      next()
    } else {
      // 如果路由不存在白名單裡,那就跳轉到登入頁 并帶上上次通路的路由
      next(`/login?redirect=${to.path}`)
      // 結束滾動條
      NProgress.done()
    }
  }
})
 
router.afterEach(() => {
  // 結束滾動條
  NProgress.done()
})      

流程圖:

element ui的vue-element-admin背景內建方案