Vue 后台管理系统权限控制

266 阅读3分钟

一.分工

    在曾经的某个项目中,每个账号有其所属的角色,每个角色有各自可以登录的系统权限和可以查看的菜单.页面.按钮权限

    后端控制:

        1.该账号属于哪个角色。

        2.该角色有没有权限登录该系统(因为有对应的tob网站)。

        3.有没有权限调用接口。

        4.该角色所拥有的菜单和按钮的权限数据。

    前端控制:

        1.菜单的动态展示和动态路由配置。

            避免用户直接地址栏输入进入没权限的页面,需要进行动态路由配置

        2.按钮级别的权限控制(自定义指令)。

二.实现

    实现思路:准备基础路由。登陆时将用户拥有权限的路由使用addRoutes添加到路由表里。

    1.后端返回的数据很多包括了路由配置里的数据,需要自己格式化

        缺点:后端需要按照前端需要的路由层级返回数据,有一个数据对不上就会出问题,需要前端填写很多数据,角色权限和路由表对不上等等,所以没有选择这个方式

    2.前端写好路由表,在meta里配置好权限的code,根据后端返回的菜单权限code匹配

        优点:只需要绑定一个数据,路由数据不会出错

三.常见问题

    1.页面刷新 地址栏直接输入 进不去路由

       这两种情况打出日志发现动态添加的路由清空了,所以进不去或者直接进404

       解决方法:将角色的codelist保存到本地存储里,当路由onready时重新添加动态添加

//generateRoutes.js
function generateRoutes(list) {  // 1.去localStorage里拿codelist  // 2.根据codelist获取路由表  // 3.添加到当前路由中  router.addRoutes(list)
  // vue-router4.x中废弃该api改为addRoute onReady改为isReady}

// router/index.js
router.onReady(() => {  generateRoutes(list)})

    2.退出再登录时提示重复添加路由

         封装resetRouter函数,在用户退出登录时调用,清空路由表

router/index.js
const createRouter = () => {  return new VueRouter({    mode: 'history',    base: process.env.BASE_URL,    routes  })}
export function resetRouter() {
  const newRouter = createRouter();
  router.matcher = newRouter.matcher;
}

    3.动态添加完路由,路由跳转失败或直接进404页面

        看网上有很多帖子说是因为新加的路由在统配符的路由的后面,所以解决方法是配置404页面,动态添加路由后再次动态添加*的路由重定向到404页面。

        我没有遇到过这个问题,但是我的基础路由配置里面是有*的路由,而且我在动态添加路由后输出路由表的时候他也是在最后的,所以遇到后可以先输出试试

四.按钮级权限控制

    用的自定义指令去控制按钮的显示

import Vue from 'vue'import store from '@/store'/** * 操作权限 * v-permission可直接控制模块是否显示 * 全局方法$permission返回是否显示true/false */Vue.directive('permission', {  bind: function(el, binding, vnode) {    if (!Vue.prototype.$hasPermission(binding.value)) {      el.remove()    }  }})Vue.prototype.$hasPermission = function(value) {  let perms  // 判断是单个权限还是多个权限  switch (typeof value) {    case 'string':      perms = [value]      break    case 'object':      if (value instanceof Array) {        perms = value      }      break    default:      perms = []      break  }  const storePerms = store.state.user.nowPower  const has = perms.every(item => {    return storePerms.includes(item)  })  return has}Vue.prototype.$notPerm = function(value) {  return !Vue.prototype.$hasPermission(value)}

五.总结

    用的方法还是比较常见的vue控制后台管理系统权限的方法,实际在项目中应用起来还是需要调整,比如路由组件需不需要keep-alive等等。