设计思想
RBAC的权限模型:RBAC(Role-Based Access control),也就是基于角色的权限分配解决方案 实现的目标:不同权限的员工登录可以有不同的权限数据

分配权限
注册增加一个弹层组件
<template><!-- 分配权限的弹层 --><el-dialogtitle="分配权限(一级为路由页面查看权限-二级为按钮操作权限)":visible="showAssignDialog"><!-- 权限点数据展示 --><template #footer><div style="text-align: right;"><el-button @click="closeAssignDialog">取消</el-button><el-button type="primary">确定</el-button></div></template></el-dialog></template><script>export default {props: {showAssignDialog: {type: Boolean,default: false}}}</script><style></style>
添加控制弹层的打开关闭 父传子,子传父 渲染使用el-tree组件
<template><!-- 分配权限的弹层 --><el-dialogtitle="分配权限(一级为路由页面查看权限-二级为按钮操作权限)":visible="showAssignDialog"@close="closeAssignDialog"@open="openDialog"><el-tree:data="permissionList":props="{ label: 'name' }":default-expand-all="true":show-checkbox="true":check-strictly="true"node-key="id"/><!-- 权限点数据展示 --><template #footer><div style="text-align: right;"><el-button @click="closeAssignDialog">取消</el-button><el-button type="primary">确定</el-button></div></template></el-dialog></template><script>import { getPermissionList } from '@/api/permission'import transTree from '@/utils/transTree.js'export default {props: {showAssignDialog: {type: Boolean,default: false}},data() {return {permissionList: []}},methods: {closeAssignDialog() {this.$emit('close_dialog')},async openDialog() {const res = await getPermissionList()this.permissionList = transTree(res.data)}}}</script><style></style>
添加权限
使用组件方法
node-key="id"可以更改获取到的数据属性为id getCheckedKeys()获取到所有选中节点的id
async confirm() {await assignPerm({id: this.curId,permIds: this.$refs.tree.getCheckedKeys()})this.$message.success('分配权限成功')this.closeAssignDialog()}
数据回显
用到tree组件方法setCheckedKeys,达成数据回显
async openDialog() {const res = await getPermissionList()this.permissionList = transTree(res.data)// 数据回显 调用组件方法const resd = await getRoleDetailById(this.curId)this.$refs.tree.setCheckedKeys(resd.data.permIds)},
分配角色
注册组件 完成弹层的打开和关闭
<template><el-dialog class="assign-role" title="分配角色" :visible="showRoleDialog"><!-- 这里准备复选框 --><template #footer><el-button type="primary" size="small">确定</el-button><el-button size="small">取消</el-button></template></el-dialog></template><script>export default {props: {showRoleDialog: {type: Boolean,default: false}}}</script>
获取角色列表 在open事件中 渲染到复选框中 选框组 显示的内容是绑定的选项 如果需要显示别的属性可以使用插值表达式{{}}在里面出来
<template><el-dialogclass="assign-role"title="分配角色":visible="showRoleDialog"@close="closeRoleDialog"@open="openDialog"><!-- 这里准备复选框 --><el-checkbox-group v-model="checkList"><el-checkbox v-for="item in list" :key="item.id" :label="item.id">{{ item.name }}</el-checkbox></el-checkbox-group><template #footer><el-button type="primary" size="small" @click="confirm">确定</el-button><el-button size="small" @click="closeRoleDialog">取消</el-button></template></el-dialog></template><script>import { getRoleListApi } from '@/api/setting'export default {props: {showRoleDialog: {type: Boolean,default: false},id: {type: String,default: ''}},data() {return {checkList: [],list: [],curId: ''}},methods: {closeRoleDialog() {this.$emit('close-dialog')},async openDialog() {const res = await getRoleListApi()this.list = res.data.rows// this.curId = this.id// console.log(this.list)// 数据回显},}}</script>
分配功能完善 需要id 和 选中的角色数组 id通过父传子获取
/*** @description: 为用户分配角色* @param {*} data { id:当前用户id, roleIds:选中的角色id组成的数组 }* @return {*}*/export function assignRoles(data) {return request({url: '/sys/user/assignRoles',data,method: 'put'})}
async confirm () {await assignRoles({ id: this.id, roleIds: this.checkList })this.$message.success('分配角色成功')// 关闭弹层this.$emit('close-dialog')}
数据回显 根据id查询角色信息 将获取到的角色数组赋值个给绑定数组,达到回显
import { getUserInforMationApi } from '@/api/user'async openDialog() {const res = await getRoleListApi()this.list = res.data.rows// this.curId = this.id// console.log(this.list)// 数据回显const { data } = await getUserInforMationApi(this.id)this.checkList = data.roleIds// console.log(data)},
权限应用

所谓的路由系统浏览器中输入path,可以渲染出来一个对应的component
RBAC权限思想和实际应用RBAC概念
- 基于角色的权限控制思想 流程 用户 角色 权限点三个主体
- 首先给用户分别配角色 然后给角色分配权限点
为什么要进行基于角色的设计
- 最开始用户和权限点 形成多对多的关系杂乱 员工一旦离职 需要把所有的权限解绑 新入一个员工又得把所有的权限点再重新分配一次
- 加入了角色 把权限数据直接都分配给固定的几个角色,新员工入职只需要配置一次权限点和角色关系 任何一个员工进来都可以和酷爱的得到应有的权限
员工管理 + 角色管理 + 权限点管理
- 角色模块是为了员工服务的 给员工分配角色
- 权限点模块是为了角色服务的 给角色分配权限点
路由系统的动态加入
- 得到menus权限数据+ 本地存储的动态完整的路由表
- 以menus为主对动态路由表做过滤筛选
- 调用一个router的实例方法 addRouters 加入路由系统
菜单显示控制
- 解决方法vuex 需要满足
- 动态操作
- 影响视图的渲染
- 多模块共享
- 以静态路由表定义state 以拼写静态+筛选之后的动态作为mutation函数
准备两个数据
获取动态路由表和个人信息
// 路由表import { asyncRoutes } from '@/router'// 获取角色信息 这里用的是下面方法的返回值const res = await store.dispatch('user/getUserInfoAction')console.log(res)console.log(asyncRoutes)
过滤
用获得的信息过滤路由
const filterRouters = asyncRoutes.filter(item => menus.includes(item.children[0].name))
加入路由系统
动态路由表 动态添加 将过滤好的路由表加入,让路由可用 将路由配置中的动态路由表删除,将过滤后的路由数组添加到路由系统中 使用addRoutes方法
router.addRoutes(filterRouters)
渲染到左侧菜单
路由渲染的是所有的静态路由 用vuex来保存数据这样就变成了响应式的
import { constantRoutes } from '@/router/index'export default {namespaced: true,state: {menus: {}},mutations: {setMunes(state, payload) {state.menus = { ...constantRoutes, ...payload }}}}
store.commit('menu/setMunes', filterRouters)
return this.$store.state.menu.menus
退出登录重置路由
本质上addRouter方法是一个累加的方法 退出登录会执行user/reset_state方法,在方法内重置路由
按钮指令
Vue.directive inserted(el,binding) 指令挂载的元素完成渲染时自动执行的钩子函数
el:指令绑定的dom元素binding.value:指令等于好后面的表达式 获取当前的父节点 移除子节点el.parentNode.removeChild(el)
