vue實現(xiàn)動態(tài)路由權(quán)限

要做動態(tài)路由權(quán)限,首先要更改這個文件"\src\layout\components\Sidebar\index.vue"

image.png

將原本獲取本地路由代碼,修改成你處理過的路由,我的路由都是本地,但是在路由的meta中定義了參數(shù)以此來過濾是否含有權(quán)限。
image.png

登錄之后,會返回數(shù)據(jù)兩個字段,對應(yīng)我這兩個自定義字段,我在vuex中寫了文件來進(jìn)行過濾篩選。
文件路徑
"\src\store\modules\permission.js"

import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPoduct(poduct, tmp) {
  if (tmp.meta && tmp.meta.product) {
    return tmp.meta.product.some(ele => ele.includes(poduct))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, obj) {
  const res = []
  var product = obj.product
  var perms = obj.perms
  //  處理獲取一級導(dǎo)航欄
  routes.forEach((route, index) => {
    const tmp = { ...route }
    if (hasPoduct(product, tmp)) {
      perms.forEach(item => {
        tmp.meta.perm.forEach(items => {
          if (item === items) {
            res.push(tmp)
          }
        })
      })
    }
  })
  const hasLibrary = window.localStorage.getItem('hasLibrary')
  // const hasLibrary = getCookie('hasLibrary')
  res.forEach((route, index) => {
    var child = []
    res[index].children.forEach((items, indexs) => {
      //  console.log(items.path!='book')
      const tmp = { ...items }
      if (hasLibrary === 'false' && items.path !== 'book') {
        if (hasPoduct(product, tmp)) {
          perms.forEach(item => {
            if (tmp.meta.perm) {
              tmp.meta.perm.forEach(permitems => {
                if (item === permitems) {
                  if (child.indexOf(tmp) === -1) {
                    child.push(tmp)
                  }
                }
              })
            }
          })
        }
      } else if (hasLibrary === 'true') {
        if (hasPoduct(product, tmp)) {
          perms.forEach(item => {
            if (tmp.meta.perm) {
              tmp.meta.perm.forEach(permitems => {
                if (item === permitems) {
                  if (child.indexOf(tmp) === -1) {
                    child.push(tmp)
                  }
                }
              })
            }
          })
        }
      }
    })
    res[index].children = child
  })
  //  console.log(res)
  return res
}

const state = {
  // 全局路由
  routes: [],
  addRoutes: [],
  // 獲取產(chǎn)品權(quán)限數(shù)據(jù)
  product: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  },
  CHANGE_ROUTES(state, value) {
    state.routes = value
  },
  CHANGE_PRUDUCT: (state, value) => {
    state.product = value
  }
}

const actions = {
  generateRoutes({ commit }, obj) {
    return new Promise(resolve => {
      var accessedRoutes
      accessedRoutes = filterAsyncRoutes(asyncRoutes, obj)
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  },
  changeRoutes({ commit }, data) {
    commit('CHANGE_ROUTES', data)
  },
  changeProduct({ commit }, data) {
    commit('CHANGE_PRUDUCT', data)
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

然后使用路由守衛(wèi)進(jìn)行判斷"\src\permission.js"

import store from './store';
import { constantRoutes } from '@/router';
import router, { resetRouter } from '@/router';
import { getCookie } from '@/utils/auth';
router.beforeEach(async(to, from, next) => {
  const role = await getCookie('username');
  if (to.path !== '/login') {
    // 判斷用戶是否已經(jīng)登陸
    if (role) {
      // 判斷手動輸入的路由是否存在
      const product = window.localStorage.getItem('product');
      const perms = JSON.parse(window.localStorage.getItem('perms'));
      // 先判斷產(chǎn)品是否可展示
      if (product && perms) {
        // 先判斷當(dāng)前路由是否有產(chǎn)品的權(quán)限
        if (to.meta) {
          if (to.meta.product) {
            if (to.meta.product.some(ele => ele.includes(product))) {
              if (to.meta.perm) {
                to.meta.perm.forEach(item => {
                  if (perms && perms.includes(item)) {
                    next();
                  }
                });
              }
            } else {
              next('/404');
            }
          } else {
            next();
          }
        } else {
          next('/404');
        }
      } else {
        next();
      }
    } else {
      next({ path: '/login' });
    }
  } else {
    next();
  }
});
// 設(shè)置路由守衛(wèi)  動態(tài)設(shè)置路由
router.afterEach(async(to, from) => {
  // const accessRoutes =await asyncRoutes;
  // 動態(tài)添加路由到router內(nèi)
  resetRouter();
  var product = '';
  var perms = '';
  const role = await getCookie('username');
  if (role) {
    product = window.localStorage.getItem('product');
    perms = JSON.parse(window.localStorage.getItem('perms'));
    // product = getCookie('product');
    // perms = getCookie('perms');
    var obj = '';
    if (product && perms) {
      obj = {
        product: product,
        perms: perms
      };
      store.dispatch('permission/generateRoutes', obj);
      const result = await store.state.permission.addRoutes;
      router.addRoutes(result);
    }
  }
});

注意:路由守衛(wèi)中一定要一步一步判斷,不符合要調(diào)用next(),否則會形成死循環(huán)且在獲取數(shù)據(jù)的時候一定要注意異步。
在main.js導(dǎo)入
import './permission';

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容