一.分工
在曾经的某个项目中,每个账号有其所属的角色,每个角色有各自可以登录的系统权限和可以查看的菜单.页面.按钮权限
后端控制:
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等等。