美文网首页前端开发那些事儿
vue实现动态路由权限

vue实现动态路由权限

作者: 陶菇凉 | 来源:发表于2020-12-20 11:56 被阅读0次

要做动态路由权限,首先要更改这个文件"\src\layout\components\Sidebar\index.vue"

image.png
将原本获取本地路由代码,修改成你处理过的路由,我的路由都是本地,但是在路由的meta中定义了参数以此来过滤是否含有权限。
image.png
登录之后,会返回数据两个字段,对应我这两个自定义字段,我在vuex中写了文件来进行过滤筛选。
文件路径
"\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
  //  处理获取一级导航栏
  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: [],
  // 获取产品权限数据
  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
}

然后使用路由守卫进行判断"\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') {
    // 判断用户是否已经登陆
    if (role) {
      // 判断手动输入的路由是否存在
      const product = window.localStorage.getItem('product');
      const perms = JSON.parse(window.localStorage.getItem('perms'));
      // 先判断产品是否可展示
      if (product && perms) {
        // 先判断当前路由是否有产品的权限
        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();
  }
});
// 设置路由守卫  动态设置路由
router.afterEach(async(to, from) => {
  // const accessRoutes =await asyncRoutes;
  // 动态添加路由到router内
  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);
    }
  }
});

注意:路由守卫中一定要一步一步判断,不符合要调用next(),否则会形成死循环且在获取数据的时候一定要注意异步
在main.js导入
import './permission';

相关文章

网友评论

    本文标题:vue实现动态路由权限

    本文链接:https://www.haomeiwen.com/subject/kxaqnktx.html