1、弹出分配权限的对话框并请求权限数据
先给分配按钮添加点击事件:
<el-button size="mini" type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row.id)">分配权限</el-button>
添加分配权限对话框:
<!--分配角色权限的对话框--> <el-dialog title="分配权限" :visible.sync="setRightDialogVisible" width="50%"> <!--内容主体区域--> 111 <!--底部按钮区域--> <span slot="footer" class="dialog-footer"> <el-button @click="setRightDialogVisible = false">取 消</el-button> <el-button type="primary" @click="setRightDialogVisible = false">确 定</el-button> </span> </el-dialog> <script> export default { data() { return { setRightDialogVisible: false, // 控制分配角色权限对话框是否显示 rightsList: [] // 角色所有权限数据 } }, methods: { // 展示分配权限的对话框 async showSetRightDialog(id) { this.setRightDialogVisible = true // 获取所有权限列表 树形 const { data: res } = await this.$http.get('rights/tree') console.log(res) if (res.meta.status !== 200) { return this.$message.error('获取权限列表失败') } this.rightsList = res.data } } } </script>
2、分配并使用el-tree树形控件
先把Tree添加引入到element.js,这里就不写了。
然后找到el-tree的实例代码:show-checkbox 节点是否可被选择
<!--内容主体区域 树形控件--> <el-tree :data="rightsList" :props="defaultProps" show-checkbox></el-tree> <script> export default { data() { return { // 树形控件的属性绑定对象 treeProps: { label: 'authName', children: 'children' } } } } </script>
效果图:
3、优化树形控件的显示UI
node-key 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
default-expand-all 是否默认展开所有节点
<!--内容主体区域 树形控件--> <el-tree :data="rightsList" :props="treeProps" show-checkbox default-expand-all node-key="id"></el-tree>
4、加载当前角色的已有权限
default-checked-keys 默认勾选的节点的 key 的数组
<!--内容主体区域 树形控件--> <el-tree :data="rightsList" :props="treeProps" show-checkbox default-expand-all :default-checked-keys="defKeys" node-key="id"></el-tree> <script> export default { data() { return { defKeys: [] // 默认选中的节点ID值数组 } } } </script>
把权限的id放入到defKeys数组中。
点击分配权限按钮的同时,把当前角色已有的三级权限的id都放入到defKeys数组中。
// 展示分配权限的对话框 async showSetRightDialog(role) { // 获取所有权限列表 树形 const { data: res } = await this.$http.get('rights/tree') // console.log(res) if (res.meta.status !== 200) { return this.$message.error('获取权限列表失败') } this.rightsList = res.data // 嵌套循环获取三级节点的id var arr = [] // console.log(role.children) var children1 = role.children for (var i = 0; i < children1.length; i++) { var children2 = children1[i].children // console.log(children2) for (var j = 0; j < children2.length; j++) { var children3 = children2[j].children // console.log(children3) for (var k = 0; k < children3.length; k++) { arr.push(children3[k].id) } } } this.defKeys = arr this.setRightDialogVisible = true },
也可以先创建一个递归函数:
// 通过递归的形式,获取角色下所有三级权限的id,并保存到defKeys数组中 getLeafKeys(node, arr) { // 节点 数组 // 如果当前node节点不包含children属性,则是三级权限节点 if (!node.children) { return arr.push(node.id) } // 循环node里的children数组,每循环一项拿到一个子节点item,在根据item再次调用递归函数getLeafKeys, // 然后把当前的item当做一个节点传进去,同时把arr传进去。只要递归完毕后,就把三级节点的id都保存到arr了 node.children.forEach(item => this.getLeafKeys(item, arr)) }
然后调用递归函数:
// 展示分配权限的对话框 async showSetRightDialog(role) { // 获取所有权限列表 树形 const { data: res } = await this.$http.get('rights/tree') console.log(res) if (res.meta.status !== 200) { return this.$message.error('获取权限列表失败') } this.rightsList = res.data // 递归获取三级节点的id this.getLeafKeys(role, this.defKeys) this.setRightDialogVisible = true },
分配权限按钮加上scope.row:
<el-button size="mini" type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row)">分配权限</el-button>
此时点击分配按钮,弹出的对话框如图:
5、小bug,在关闭分配权限对话框时重置defKeys数组为空
给对话框绑定close事件:
<!--分配角色权限的对话框--> <el-dialog title="分配权限" :visible.sync="setRightDialogVisible" width="50%" @close="showSetRightDialogClosed">
showSetRightDialogCloseds事件:
// 监听 分配权限对话框的关闭事件 showSetRightDialogClosed() { this.defKeys = [] }
当然也可以在打开对话框的时候清空defkeys数组,意思是一样的。
6、调用api接口完成分配权限功能
角色授权接口,请求路径:roles/:roleId/rights,请求方法:post,参数rids 权限 ID 列表(字符串) 以 `,` 分割的权限 ID 列表(获取所有被选中、叶子节点的key和半选中节点的key, 包括 1,2,3级节点)
rids 权限 ID 列表:就是说所有选中和半选中状态的id,然后以','分割
getCheckedKeys
若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组
(leafOnly) 接收一个 boolean 类型的参数,若为 true 则仅返回被选中的叶子节点的 keys,默认值为 false
getHalfCheckedKeys
若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点的 key 所组成的数组
给树形控件添加引用:
<!--内容主体区域 树形控件--> <el-tree :data="rightsList" :props="treeProps" node-key="id" show-checkbox default-expand-all :default-checked-keys="defKeys" ref="treeRef"></el-tree>
给确定按钮添加点击事件:
<el-button type="primary" @click="allotRigths">确 定</el-button>
添加allotRigths事件:
// 点击按钮 给角色分配权限 async allotRigths(id) { const keys = [ ...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys() ] console.log(keys) }
此时选择添加商品、商品修改、商品删除3个权限,点击确定,控制台会打印出keys数组,如下图:
然后要把keys数组的值形成一个以","拼接字符串:
const idStr = keys.join(',')
再调用角色授权接口,把Keys数组传递给rids参数:
还有请求路径要带角色ID,但是我们在确定按钮哪里获取不到角色ID,只能在点击分配按钮的时候,先把角色ID传出来
<script> export default { data() { return { roleId: '' // 当前角色id } }, methods: { // 展示分配权限的对话框 async showSetRightDialog(role) { this.roleId = role.id // 获取角色id 。。。 } } </script>
然后请求接口:
// 点击按钮 给角色分配权限 async allotRigths() { const keys = [ ...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys() ] // console.log(keys) const idStr = keys.join(',') const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: idStr }) if (res.meta.status !== 200) { return this.$message.error('更新角色权限失败!') } this.$message.success('更新角色权限成功!') this.getRolesList() this.setRightDialogVisible = false }
效果图: