vue项目的菜单权限判断的实现_vue中如何实现后台管理系统的权限控制

964c2c938bfd55705312c0d76b09e2e1.png

工作:路由是前台配,还是后台配的问题?

个人建议,前端配置,这样才能达到前后端分离的工作;

1、后台配置路由,前端人不在的情况;没办法页面跳转;
2、新的需求,前端把路由配好了,后台的人不在,没办法找到路由;

首先定义不需要权限的默认路由,

routre/index.js
**
 * 默认路由
 */
export const defaultRouterMap = [
  {
 path: "/",
 redirect: "login",
 hidden: true,
 meta: {
 name: "主页"
    }
  },
  {
 path: "/login",
 name: "Login",
 hidden: true,
 meta: {
 name: "登录"
    },
 component: () => import("../views/Login/index.vue")
  },
  {
 path: "/console",
 name: "Console",
 redirect: "index",
 meta: {
 name: "控制台",
 icon: 'console'
    },
 component: Layout,
 children: [
      {
 path: "/index",
 name: "Index",
 meta: {
 keepAlive: true,
 name: "首页"
        },
 component: resolve=>(require(["@/views/Console/index.vue"],resolve))
      }
    ]
  },

export default new Router({
  mode: 'hash',
  scrollBehavior: () => ({ y: 0 }),
  routes: defaultRouterMap
});

定义动态路由

routre/index.js
/**
 * 动态路由
 * 角色:sale, technician, manager
 */
export const asnycRouterMap = [
  {
 path: "/info",
 name: "Info",
 meta: {
 role: ['sale', 'manager'],
 system: 'infoSystem',
 name: "信息管理",
 icon: 'info'
    },
 component: Layout,
 children: [
      {
 path: "/infoIndex",
 name: "InfoIndex",
 meta: {
 keepAlive: true,
 role: ['sale', 'manager'],
 name: "信息列表"
        },
 component: () => import("../views/Info/index.vue")
      },
      {
 path: "/infoCategory",
 name: "InfoCategory",
 meta: {
 keepAlive: true,
 role: ['sale'],
 name: "信息分类"
        },
 component: () => import("../views/Info/category.vue")
      },
      {
 path: "/infoDetailed",
 name: "InfoDetailed",
 hidden: true,
 meta: {
 keepAlive: true,
 role: ['sale'],
 name: "信息详情"
        },
 component: () => import("../views/Info/detailed.vue")
      }
    ]
  },

接下来在vuex进行操作,在store新建一个js文件如permission.js,创建动态路由

store/permission.js

//获取权限接口方法
import { getUserRole } from "@/api/login";
//引入动态路由,静态路由
import { defaultRouterMap, asnycRouterMap } from "@/router"

function hasPremission(roles, router){
    if(router.meta && router.meta.role) {
        return roles.some(item => router.meta.role.indexOf(item) >= 0)
    }

}

const state = {
 allRouters: defaultRouterMap, 
 addRouters: [],
 
}
const getters = {
 allRouters: state => state.allRouters,  // 所有的
 addRouters: state => state.addRouters,  // 匹配的
 
}

const mutations = {  // 必须的  同步 没有回调处理事情
 SET_ROUTER(state, router) {
 state.addRouters = router
 state.allRouters = defaultRouterMap.concat(router)
    }
}

创建动态路由

store/permission.js
const actions = {  // 可以回调处理事情 
 /**
     * 获取用户角色 
     * @param {*} param0
     * @param {*} repuestData 
     */
 getRoles({ commit }, repuestData) {
 return new Promise((resolve, reject) => {
 getUserRole().then(response => {
 let data = response.data.data;
 resolve(data);
            })
        })
    },
 /**
     * 创建动态路由
     */
 createRouter({ commit }, data){
 return new Promise((resolve, reject) => { 
//对应router路由里meta标签里system的值,如果相同则有权限访问
 // ["infoSystem", "userSystem"]
 let role = data;
 // 超管的状态
 let addRouters = []
 if(role.includes('admin')) {
    addRouters = asnycRouterMap
  }else{ // 普通管理员 
    addRouters = asnycRouterMap.filter(item => {
       if(hasPremission(role, item)) {
 // 优先判断 
          if(item.children && item.children.length > 0) {
            item.children = item.children.filter(child => {
              if(hasPremission(role, child)){
                     return child;
                }
               })
                    return item;
              }
                    return item;
              }
        }) 
        addRouters.push(asnycRouterMap[asnycRouterMap.length - 1]);
      }
 // 更新路由
 commit('SET_ROUTER', addRouters);
 resolve()
        })
    }
}

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

这个时候我们已经拿到权限数据,并将数据存放到了vuex中,面我们需要利用返回数据匹配之前写的异步路由表,将匹配结果和静态路由表结合,开成最终的实际路由表。

为了代码简洁明白,我们在router文件夹下新建一个js文件

store/premit.js

import router from "./index";
import store from "../store/index";

import { getToKen, removeToKen, removeUserName } from "@/utils/app";

const whiteRouter = ['/login']; // indexOf方法,判断数组中是否存在指定的某个对象,如果不存在,则返回-1

// 路由守卫
router.beforeEach((to, from, next) => {
 if(getToKen()){
 if(to.path === '/login'){
 removeToKen();
 removeUserName();
 store.commit("app/SET_TOKEN", '');
 store.commit("app/SET_USERNAME", '');
 next();
        }else{
 // 获取用户的色
 // 动态分配路由权限
 /**
             * 1、什么时候处理动态路由
             * 2、以什么条件处理
             * roles[]
             */
 if(store.getters['app/roles'].length === 0) {
 store.dispatch('permission/getRoles').then(response => {
 let role = response.role;
 let button = response.button; // 这是上学时说的内容
 let btnPerm = response.btnPerm;
 store.commit("app/SET_ROLES", role);
 store.commit("app/SET_BUTTON", btnPerm);
 // 存储角色 
 store.dispatch('permission/createRouter', role).then(response => {
 let addRouters = store.getters['permission/addRouters'];
 let allRouters = store.getters['permission/allRouters'];
 // 路由更新
 router.options.routes = allRouters;
 // 添加动态路由
 router.addRoutes(addRouters)
 next({ ...to, replace: true});
 // es6扩展运算符,防止内容发生变化的情况
 // 不被记录历史记录
                    })
                });
            }else{
 next();
            }
        }
 /**
         * 1、to = /console
         * 2、to = /index
         */
 // 路由动态添加,分配菜单,每个角色分配不同的菜单
    }else{
 if(whiteRouter.indexOf(to.path) !== -1) {  // 存在
 next();  // to
        }else{
 next('/login')  // 路由指向
        }
 /**
         * 1、直接进入index的时候,参数to被改变成了 "/index",触发路由指向,就会跑beforeEach
         * 2、再一次 next 指向了login,再次发生路由指向,再跑beforeEach,参数的to被改变成了"/login"
         * 3、白名单判断存在,则直接执行next(),因为没有参数,所以不会再次beforeEach。
         */
    }
})

至此为止,由前端配置权限控制流程就差不多是这样,如果大家有疑问,或者博主有什么错误的,欢迎大家评论区留言。

如果对大家有所帮助,希望大家点赞并关注博主。谢谢大家。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值