一、角色列表模块
二、权限列表模块
0.创建权限列表组件,命名为Rights.vue
1.绘制面包屑导航和卡片视图(与用户列表模块使用方法一样)
2.调用API获取权限列表的数据
API接口
methods:{
async getRightsList(){
const {data:res} =await this.$http.get('rights/list',{
params:this.rightsList
})
// console.log(res);
if(res.meta.status !==200){
return this.$message.error('获取权限列表失败')
}
this.rightsList = res.data
// console.log(this.rightsList);
}
},
created(){
this.getRightsList()
}
3.渲染权限列表UI结构(与用户列表页面类似)
<el-card>
<el-table
:data="rightsList"
border
stripe>
<el-table-column
type="index" label="#">
</el-table-column>
<el-table-column prop="authName" label="权限名称"></el-table-column>
<el-table-column prop="path" label="路径"></el-table-column>
<el-table-column prop="level" label="权限等级">
<template v-slot="scope">
<!-- {{scope.row}} -->
<el-tag type="success" v-if="scope.row.level ==='0'">一级</el-tag>
<el-tag type="warning" v-if="scope.row.level ==='1'">二级</el-tag>
<el-tag type="danger" v-if="scope.row.level ==='2'">三级</el-tag>
</template>
</el-table-column>
</el-table>
</el-card>
效果图:
4.户-角色-权限三者之间的关系
1.创建角色列表组件,名为Roles.vue
2.绘制基本布局结构,通过API获取角色列表数据
API接口
async getRolesList(){
const {data:res} =await this.$http.get('roles',
{
param:this.rolesList})
if(res.meta.status !==200){
this.$message.error('获取角色列表失败')
}else{
this.rolesList =res.data
}
}
3.渲染角色列表数据(大部分是和其它列表渲染一样的)
这里多了一个展开列的组件标签
效果图:
5.实现添加角色信息、编辑角色信息、删除角色信息的功能(与用户管理模块的添加用户、编辑用户和删除用户类似)。
增删改三个功能实现步骤的总结、这里就以添加角色信息、编辑角色信息、删除角色信息为例。
1.添加角色
(1)首先当然是通过API获取角色的数据,把角色信息的Table渲染出来
(2)加入添加角色的弹窗框
(3)弹窗框需要在关闭的时候做重置,也需要在点确认的时候做预校验,校验通过的话
(4)预校验通过则调用添加用户的API进行添加角色
(5)然后进行把添加角色弹窗口关闭
(6)调用获取角色信息方法,重新获取角色信息
2.修改角色信息
(1)加入修改角色的弹窗框
(2)弹窗框需要在关闭的时候做重置,也需要在点确认的时候做预校验,校验通过的话
(3)预校验通过则调用修改角色信息的API进行修改角色
(4)然后进行把修改角色弹窗口关闭
(5)调用获取角色信息方法,重新获取角色信息
3.删除角色
(1)点击删除按钮时,需要弹出一个是否继续删除的警示框
(2)点击确认删除的话,则会执行删除逻辑
(3)删除一般是根据id来删除,所以可以用插槽来获取id,然后调用删除角色API来实现
(4)调用获取角色信息方法,重新获取角色信息
6.角色下权限渲染的思路(重点)
主要是通过三层for循环来分别渲染不同层级的权限
最终实现效果如图所示:
1.通过第一层for循环渲染一级权限
<el-table-column
type="expand">
<template v-slot="scope">
<!-- <pre>{{scope.row}}</pre> -->
<el-row :gutter="24" v-for="(item1,i1) in scope.row.children" :key="item1.id" >
<!-- 渲染一级权限 -->
<el-col :span="5" >
<el-tag>
{{item1.authName}}
</el-tag>
</el-col>
<!-- 渲染二级和三级权限 -->
<el-col :span="19"></el-col>
</el-row>
</template>
</el-table-column>
效果图:
(1)美化一级权限的UI结构
css代码:
// 使一级标签有一点间隙
.el-tag {
margin:7px
}
// 在一级标签的第一个标签头部加上边框
.bdtop {
border-top: 1px solid #eee;
}
// 在每一个一级标签底部加上边框
.bdbottom{
border-bottom: 1px solid #eee;
}
html代码: 注意:这里的三元表达式非常重要,和class的绑定也很重要
<el-row :class="['bdbottom',i1 ===0?'bdtop':'']" :gutter="24" v-for="(item1,i1) in scope.row.children" :key="item1.id" >
<!-- 渲染一级权限 -->
<el-col :span="5" >
<el-tag>
{{item1.authName}}
</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<!-- 渲染二级和三级权限 -->
<el-col :span="19"></el-col>
</el-row>
2.通过第二层for循环渲染二级权限
(1)代码:
<el-table-column
type="expand">
<template v-slot="scope">
<!-- <pre>{{scope.row}}</pre> -->
<el-row :class="['bdbottom',i1 ===0?'bdtop':'']" :gutter="24" v-for="(item1,i1) in scope.row.children" :key="item1.id" >
<!-- 渲染一级权限 -->
<el-col :span="5" >
<el-tag>
{{item1.authName}}
</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<!-- 渲染二级和三级权限 -->
<el-col :span="19">
<!-- 通过for循环嵌套渲染二级权限 -->
<el-row :class="[i2 ===0?'' :'bdtop']" v-for="(item2,i2) in item1.children" :key="item2.id" >
<el-col>
<el-tag type="success">{{item2.authName}}</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<el-col></el-col>
</el-row>
</el-col>
</el-row>
</template>
3.通过第三层for循环渲染三级权限
代码:
<template v-slot="scope">
<!-- <pre>{{scope.row}}</pre> -->
<el-row :class="['bdbottom',i1 ===0?'bdtop':'','vcenter']" :gutter="24" v-for="(item1,i1) in scope.row.children" :key="item1.id" >
<!-- 渲染一级权限 -->
<el-col :span="5" >
<el-tag>
{{item1.authName}}
</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<!-- 渲染二级和三级权限 -->
<el-col :span="19">
<!-- 通过for循环嵌套渲染二级权限 -->
<el-row :class="[i2 ===0?'' :'bdtop','vcenter']" v-for="(item2,i2) in item1.children" :key="item2.id" >
<el-col :span="6">
<el-tag type="success">{{item2.authName}}</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<el-col :span="18">
<el-tag type="warning" v-for="(item3,i3) in item2.children" :key="item3.id" closable @close="removeRightById()">
{{item3.authName}}
</el-tag>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
7.点击删除角色下指定权限,弹出提示框
async removeRightById(){
// 先弹窗提示是否删除
const confirmResult=await this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).catch(err => err)
// 如果用户点击确认删除按钮,则返回值为字符串 confirm
// 如果用户点击取消删除按钮,则返回值为字符串 cancel
// console.log(typeof(confirmResult));
if(confirmResult !=='confirm'){
return this.$message.info('已经取消删除')
}else{
}
}
8.完成删除角色下指定权限功能
(1)调用API,api接口如下
(2)具体实现代码:
9.弹出分配权限对话框,并请求所以权限数据
(1)获取所有权限数据API,这里获取type为tree
实现代码:
10.初步配置并使用el-tree树形控件(新组件,需注意)
实现代码如图所示:
注意:
:data代表数据源,使用的是上面通过上面API调用的所有权限数据,treeProps其中children代表的是以什么来嵌套层级关系的,lable代表各层级的名字
实现效果如图所示:
11.(重点重点,递归函数)实现角色默认权限自动勾选的需求
这里实现挺复杂的,主要就是对el-tree的使用,那么这里我就贴出为了这个功能而新增的代码吧: (1)el-tree控制组件
这两个缺一不可,这里我理解的这个id是和treeProps里面有关
(2)data里面
其中defKeys是为了对应el-tree中default-checkout-keys,如果三级权限id对应则会自动勾选
(3)方法调用
这里这个递归用的很妙,role是从插槽取出的数据-scope.row,通过递归可以取出当前角色包含的权限id值,并把它赋值给defKeys数组
这个是为了清空defKeys,当权限对话框关闭后执行,这样可以避免前面一个角色的数据保存在defKeys里面
12.调用API完成分配权限功能(不大懂)
API接口:
代码:
async allotRights(){
//...为展开运算符
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('分配权限失败')
}else{
this.$message.success('分配权限成功')
this.getRolesList()
this.setRightDialogVisible =false
}
}
},
(重点重点)getCheckedKeys()和getHalfCheckedKeys()是el-tree的方法,其中其返回的值为el-tree中node-key='id',当然你也可以把id换位authName,则得到的返回值就为各个权限的authName属性。
13.渲染分配角色的对话框
14.渲染角色列表的select下拉菜单(el-select)
实现代码:
下面以官网的select为例来解释各数据的作用:
注意 :value代表用户所选中的值与data中定义的参数双向绑定,:lable代表所看到的选项,如图所示:
:value代表你选中这项后真正选中的value值