VUE权限管理,精确控制到按钮级别
一个完整的权限系统必不可少的两个部分是:
- 控制页面元素的渲染
- 动态注册路由
控制页面元素的渲染
可以使用v-if来控制,本文提供另一种解决思路
解决思路
实现一个权限组件,需要控制渲染的元素作为权限组件的一个slot,在权限组件中控制是否渲染slot。
为了不渲染多余的标签,权限组件用JSX语法来写,通过render方法来控制slot的渲染。
权限组件接受两个props:
- module 要控制的元素在系统的哪个模块下
- element 要控制的是哪个元素
根据这两个props基本上就能够从后台返回的权限数据中,判断处出当前元素是否需要渲染。
具体的props根据不同的业务系统来确定。
权限组件代码
<script>
export default {
name: "Permission",
props: {
module: {
type: String,
default: ''
},
element: {
type: String,
default: ''
}
},
data() {
return {
}
},
computed: {
// 是否具有某个模块下的某个类型的权限
hasPermission() {
const { module, element } = this;
// 在这里就是和后台返回的权限数据做匹配的过程
}
},
render() {
const { hasPermission } = this;
// this.$slots.default[0] 即为被控制的元素
return hasPermission? this.$slots.default[0]: null
}
}
具体用法
<Permission module="module111" element="addbtn">
<button>新增按钮</button>
</Permission>
动态注册路由
- 通过addRoutes动态添加路由
- 在beforeEach中请求后台的路由数据
- 为了避免每进入一个路由就会重新请求一次数据,需要设置一个标志位
实现代码
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import store from './store'
Vue.use(Router)
// 是否注册路由的标志
let register = false;
const router = new Router({
mode: 'hash',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'Home',
component: Home
}
]
})
router.beforeEach((to, from, next) => {
let path = to.path;
// 如果进入的不是登录界面,并且没有动态注册路由(register === false) 则去注册路由
if(to.path !== '/login' && !register) {
store.dispatch('getUserPermission').then((routerData) => {
router.addRoutes(routerData);
register = true;
// 路由注册完毕时,主动触发下next()
router.push({path: path});
})
}else{
next();
}
// 在路由没注册时,此处的next()不会跳转路由
// 需要在路由动态注册完毕时,主动触发一下
next();
})
export default router