- 面包屑导航区域
<!-- 面包屑导航区 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>权限管理</el-breadcrumb-item>
<el-breadcrumb-item>角色列表</el-breadcrumb-item>
</el-breadcrumb>
- 获取所有角色列表
a. 通过解构赋值的形式获取用户列表信息
b. 将得到的用户信息渲染到卡片视图
c. 完成编辑,删除,添加功能(和用户列表中的对应功能大体相似详细见https://blog.csdn.net/weixin_44996854/article/details/117093400)
async getRolesList() {
const {data: res} = await this.$http.get('/roles')
if (res.meta.status !== 200) {
return this.$message.error('获取角色列表失败')
}
this.rolesList = res.data
},
<el-card>
<el-button type="primary" @click="addDialogVisible = true">添加角色</el-button>
<el-table :data="rolesList" border stripe>
<el-table-column type="index"></el-table-column>
<el-table-column label="角色名称" prop="roleName"></el-table-column>
<el-table-column label="角色描述" prop="roleDesc"></el-table-column>
<el-table-column label="操作" width="350px">
<template slot-scope="scope">
<el-button type="primary" size="mini" icon="el-icon-edit" @click="showEditDialog(scope.row.id)">编辑
</el-button>
<el-button type="danger" size="mini" icon="el-icon-delete" @click="removeRoleById(scope.row.id)">删除
</el-button>
<el-button type="warning" size="mini" icon="el-icon-setting" @click="showSetRightDialog(scope.row)">分配权限
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
- 角色下权限渲染
a. 添加一列展开列<el-table-column type="expand">
,并在其中添加template作用域插槽<template slot-scope="scope">
b. 通过children属性来确定循环列表嵌套的情况,并在表格中渲染出来
c. 添加表格样式
参考https://zhuanlan.zhihu.com/p/51107654
当子组件做循环显示列表 或 某一部分由外部传递进来 时,则使用 作用域插槽<body> <div id="root"> <child> <template slot-scope="props"> <h1>{{props.item}}</h1> </template> </child> </div> <script> Vue.component('child', { data: function(){ return { list: [1, 2, 3, 4] } }, template: `<div> <ul> <slot v-for="item of list" :item=item ></slot> </ul> </div>` }) var vm = new Vue({ el:'#root' }) </script> </body>
子组件向父组件插槽里传数据,如 :item=item
父组件接收数据并需在外层使用 作用域插槽(必须用) ,同时声明属性名 接收子组件传递的数据,如
slot-scope=“props” , 然后在dom标签使用该数据,通常用插值表达式接收具体数据。
<!-- 展开列-->
<el-table-column type="expand">
<template slot-scope="scope">
<el-row :class="['bdbottom',i1 === 0? 'bdtop':'', 'vcenter']" v-for="(item1,i1) in scope.row.children" :key="item1.id">
<el-col :span="5">
<el-tag closable @close="removeRightById(scope.row, item1.id)">{{item1.authName}}</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<el-col :span="19">
<el-row v-for="(item2,i2) in item1.children" :key="item2.id" class="vcenter">
<el-col :span="6" :class="[i2 === 0 ? '' : 'bdtop']">
<el-tag type="success" closable @close="removeRightById(scope.row, item2.id)">{{item2.authName}}</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<el-col :span="18">
<el-tag type="warning"
v-for="(item3) in item2.children"
:key="item3.id"
closable
@close="removeRightById(scope.row,item3.id)">
{{item3.authName}}
</el-tag>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
</el-table-column>
- 删除角色下指定权限
a. 为tag标签添加删除的小图标,添加属性closable"
b. 添加弹出框,添加捕获取消事件
c. 向服务器发送delete请求给role.children重新赋值(也可以直接this.getRolesList()
,但是这样会导致下拉框关闭)
<el-tag type="success" closable @close="removeRightById(scope.row, item2.id)">{{item2.authName}}</el-tag>
async removeRightById(role,rightId){
console.log(rightId)
const confirmResult = await this.$confirm(
'此操作将永久删除该权限, 是否继续?',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).catch(err => err)
if (confirmResult !== 'confirm'){
return this.$message.info('已取消权限删除')
}
const {data : res} = await this.$http.delete(
`roles/${role.id}/rights/${rightId}`
)
if (res.meta.status !== 200) {
return this.$message.error('删除权限失败!')
}
role.children = res.data
},
- 添加分配权限对话框
a. 添加分配权限对话框
b. 设置setRightDialogVisible
变量并初始化为false控制权限对话框的显示与隐藏
c. 通过get的方式获取权限树
d. 添加el-tree
控件,指定数据源为rightsList
,规则为treeProps: { label: 'authName', children: 'children' },
e. 树形控件默认全部展开default-expand-all
,添加复选框show-checkbox
f. 实现已有元素默认勾选:设置默认选中的节点:default-checked-keys="defKeys"
,点击按钮的同时立即调用getLeafkeys
方法,将当前角色身上所有的已有权限对应三级节点的id添加到defKeys
中。
g. 添加对话框的关闭事件@close="setRightDialogClosed"
,每次对话框关闭时清空defKeys
h. 添加权限持久化:在弹出添加权限对话框函数showSetRightDialog
中添加this.roleId = role.id
得到当前角色的id值,为确定按钮绑定添加权限的函数allotRights
:将全选中的数组和半选中的数组赋值给变量keys,通过post请求发送给后台,修改用户的权限值。
<!-- 分配权限 -->
<el-dialog
title="分配权限"
:visible.sync="setRightDialogVisible"
width="50%"
@close="setRightDialogClosed">
<el-tree
:data="rightsList"
:props="treeProps"
show-checkbox
node-key="id"
default-expand-all
:default-checked-keys="defKeys"
></el-tree>
<span slot="footer" class="dialog-footer">
<el-button @click="setRightDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="allotRights">确 定</el-button>
</span>
</el-dialog>
// 通过递归 获取角色下三级权限的 id,并保存到defKeys数组中
getLeafkeys(node,arr){
if (!node.children) {
return arr.push(node.id)
}
node.children.forEach(item => this.getLeafkeys(item,arr))
},
// 弹出添加权限对话框
async showSetRightDialog(role){
this.roleId = role.id
const { data:res} = await this.$http.get('rights/tree')
if (res.meta.status !== 200) {
return this.$message.error('获取权限数据失败! ')
}
// 获取权限树
this.rightsList = res.data
this.getLeafkeys(role,this.defKeys)
this.setRightDialogVisible = true
},
//权限对话框关闭事件
setRightDialogClosed(){
this.defKeys = []
},
// 添加权限
async allotRights() {
// 将全选的keys和半选的keys合并成一个数组
const keys = [
...this.$refs.treeRef.getCheckedKeys(),
...this.$refs.treeRef.getHalfCheckedKeys(),
]
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.getRolesList()
this.setRightDialogVisible = false
}
- 完善用户列表分配角色的功能
a. 添加分配角色对话框
b. 设置setRoledialogVisible
变量并初始化为false
控制权限对话框的显示与隐藏
c. 添加分配角色按钮的@click="setRole(scope.row)"
事件
d. 添加setRole
函数:得到用户详细信息userInfo
,通过get方法获取角色列表信息
e. 分配角色对话框中渲染用户详细信息
f. 分配角色对话框中添加Select 选择器,绑定model值v-model="selectedRoleId"
,el-option
中:label
表示看到的文本,:value
表示真正选中的值。
g. 发送this.$http.put(
users/${this.userInfo.id}/role,{ rid: this.selectedRoleId })
请求,修改角色信息。
<!--分配角色对话框-->
<el-dialog
title="分配角色"
:visible.sync="setRoleDialogVisible"
width="30%"
@close="setRoleDialogClosed"
>
<p>当前的用户: {{userInfo.username}}</p>
<p>当前的角色: {{userInfo.role_name}}</p>
<el-select v-model="selectedRoleId" placeholder="请选择">
<el-option
v-for="item in rolesList"
:key="item.id"
:label="item.roleName"
:value="item.id">
</el-option>
</el-select>
<span slot="footer" class="dialog-footer">
<el-button @click="setRoleDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="saveRoleInfo">确 定</el-button>
</span>
</el-dialog>
// 展示分配角色对话框
async setRole(userInfo){
this.userInfo = userInfo
const {data:res}=await this.$http.get('roles')
if (res.meta.status !== 200){
return this.$message.error('获取角色列表失败')
}
this.rolesList = res.data
this.setRoleDialogVisible = true
},
// 点击按钮分配角色
async saveRoleInfo(){
if (!this.selectedRoleId){
return this.$message.error('请选择要分配的角色!')
}
const {data: res} = await this.$http.put(`users/${this.userInfo.id}/role`,{
rid: this.selectedRoleId
})
if (res.meta.status !== 200){
return this.$message.error(res.meta.msg)
}
this.$message.success('更新角色成功!')
this.getUserList()
this.setRoleDialogVisible = false
},
// 监听分配角色对话框的关闭事件
setRoleDialogClosed(){
this.selectedRoleId = ''
this.userInfo = {}
}
- 提交到本地仓库并推送到码云
a. 添加到本地仓库git add .
b. 提交本次修改git commit -m "完成了权限功能的开发"
c. push到远程仓库的rights分支git push
d. 切换到主分支git checkout master
e. rights分支合并到主分支git merge rights
f. 主分支推送到远程仓库git push