权限列表
权限列表
创建新分支 rights 并push到远程仓库
1 通过路由展示权限列表组件
components下建power文件夹,下建 Rights.vue
//index.js(router)
import Rights from '../components/power/Rights';
{ path: '/rights', component: Rights } //home 的 children
2 绘制面包屑和卡片视图
<!-- 面包屑导航区 -->
<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>
<!-- 卡片视图区 -->
<el-card>
123
</el-card>
3 调用API获取权限列表的数据
data() { return { rightsList: [] } }, // 权限列表
created() { this.getRightsList()},
methods: {
async getRightsList() {
const { data: res } = await this.$http.get("rights/list")
if (res.meta.status != 200)
return this.$message.error("获取权限列表失败!")
this.rightsList = res.data
console.log(this.rightsList)
}
}
4 渲染权限列表的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 slot-scope="scope">
<el-tag v-if="scope.row.level==='0'">一级</el-tag>
<el-tag type="success" v-else-if="scope.row.level==='1'">二级</el-tag>
<el-tag type="warning" v-else>三级</el-tag>
</template>
</el-table-column>
</el-table>
</el-card>
//element.js
import { Tag } from 'element-ui'
Vue.use(Tag)
角色列表
1 通过路由展示角色列表组件
components power文件夹,下建 Roles.vue
//index.js(router)
import Roles from '../components/power/Roles';
{ path: '/roles', component: Roles } //home 的 children
2 绘制基本布局并获取列表数据
<!-- 面包屑导航区 -->
<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>
<!-- 卡片视图区 -->
<el-card>
<!-- 添加角色按钮 -->
<el-row>
<el-col :span="4">
<el-button type="primary">添加用户</el-button>
</el-col>
</el-row>
</el-card>
data(){ return{ roleList:[] }},
created(){ this.getRolesList()},
methods:{
async getRolesList(){
const { data: res } = await this.$http.get('roles')
if (res.meta.status != 200)
return this.$message.error("获取用户列表失败!")
this.roleList = res.data
}
}
3 渲染角色列表数据
<!-- 角色列表区域 -->
<el-table :data="roleList" border stripe>
<!-- 展开列 -->
<el-table-column type='expand'></el-table-column>
<el-table-column type='index' label="#"></el-table-column>
<el-table-column prop="roleName" label="角色名称"></el-table-column>
<el-table-column prop="roleDesc" label="角色描述" ></el-table-column>
<el-table-column label="操作" width="300px">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="mini">编辑</el-button>
<el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
<el-button type="warning" icon="el-icon-setting" size="mini">分配权限</el-button>
</template>
</el-table-column>
</el-table>
4 分析角色下权限渲染的实现思路
<!-- 展开列 -->
<el-table-column type="expand">
<template slot-scope="scope">
<pre>
{{scope.row}}
</pre>
</template>
</el-table-column>
5 通过第一层for循环渲染一级列表
6 美化一级权限的UI结构
<!-- 展开列 -->
<el-table-column type="expand">
<template slot-scope="scope">
<el-row :class="['bdbottom',i1 === 0 ?'bdtop':'']" 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>
</template>
</el-table-column>
.bdtop{ border-top: 1px solid #eee; }
.bdbottom{ border-bottom: 1px solid #eee; }
7 通过第二层for循环渲染二级权限
8 通过第三层for循环渲染三级权限
一行24个格子 (span)
<!-- 展开列 -->
<el-table-column type="expand">
<template slot-scope="scope">
<el-row :class="['bdbottom',i1 === 0 ?'bdtop':'']" v-for='(item1,i1) in scope.row.children' :key='item1.id' class="vcenter">
<!-- 渲染一级权限 -->
<el-col :span="5">
<el-tag>{{item1.authName}}</el-tag>
<i class='el-icon-caret-right'></i>
</el-col>
<!-- 渲染二级和三级权限 -->
<el-col :span="19">
<el-row :class="[ i2=== 0 ? '':'bdtop']" v-for='(item2,i2) in item1.children' :key='item2.id' class="vcenter">
<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'>{{item3.authName}}</el-tag>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
</el-table-column>
.vcenter{
display: flex;
align-items: center;
}
9 美化角色权限下的UI结构
global.css
html,body,#app { min-width: 1366px;} /* 屏幕宽不足1366,强制最小1366,防止换行 */
10 完成删除指定角色下权限的功能
<el-tag closable @close="removeRightById(scope.row,item1.id)">{{item1.authName}}</el-tag>
<el-tag closable @close="removeRightById(scope.row,item2.id)">{{item2.authName}}</el-tag>
<el-tag closable @close="removeRightById(scope.row,item3.id)">{{item3.authName}}</el-tag>
// 根据ID删除对应权限
async removeRightById(role,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){
this.$message.error('"取消权限失败!')
}
this.$message.success('取消权限成功!')
// this.getRolesList() 不建议,会重新渲染整个页面
role.children = res.data
}
}
分配权限
1 弹出分配权限对话框并请求权限数据
<el-button type="warning" icon="el-icon-setting" size="mini" @click="setRightDialog" >分配权限</el-button >
<!-- 分配权限对话框 -->
<el-dialog title="分配权限" :visible.sync="setRightDialogVisible" width="50%" >
<span>这是一段信息</span>
<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>
data() {
return{
setRightDialogVisible:false, // 分配权限对话框
rightlist: {} // 查询到的权限信息
}
}
methods:{
// 展示分配权限的对话框
async setRightDialog() {
// 获取所有权限的数据
const {data:res} = await this.$http.get('rights/tree')
if(res.meta.status!=200){
return this.$message.error('获取权限数据失败!')
}
this.rightlist= res.data
this.setRightDialogVisible=true
}
}
}
2 初步配置并使用el-tree树形控件
<!-- 树形控件 -->
<el-tree :data="rightlist" :props="treeProps" ></el-tree> //:props 指定属性绑定对象
data() {
return{
// 树形控件属性绑定对象
treeProps:{
label:'authName', //看到的是哪个属性对应的值
children:'children' //父子间通过哪个属性嵌套
}
}
//element.js
import { Tree } from 'element-ui'
Vue.use(Tree)
3 优化树形控件的展示效果
<el-tree :data="rightlist" :props="treeProps" show-checkbox node-key='id' default-expand-all></el-tree>
4 分析已有权限默认勾选的实现思路并加载角色已有的权限
<el-button @click="setRightDialog(scope.row)">分配权限</el-button>
<!-- 树形控件 -->
<el-tree :default-checked-keys='defKeys'></el-tree>
data() { return { defKeys:[] } } // 默认选中的节点id值数组
methods:{
async setRightDialog(role) {
.....
// 递归获取角色项所以三级权限id
this.getLeafKeys(role, this.defKeys)
this.setRightDialogVisible = true
},
// 递归获取角色项所以三级权限id 保存到 defKeys
getLeafKeys(node, arr) {
// 如果是三级节点
if (!node.children) { return arr.push(node.id) }
node.children.forEach(item => this.getLeafKeys(item, arr))
}
}
5 在关闭对话框时重置defKeys数组
每次点分配权限按钮时会出现缓存现象,所以我们需要对数组进行清空,当关闭对话框时应该进行一次清空
<!-- 分配权限对话框 -->
<el-dialog @close='setRightDialogClosed'>
methods:{
// 监听分配权限对话框关闭事件
setRightDialogClosed() { this.defKeys = [] }
}
6 调用API完成分配权限的功能
<el-button @click="setRightDialog(scope.row)">分配权限</el-button >
<el-button type="primary" @click="allotRights">确 定</el-button>
</span>
data() { return { roleId: "" }
methods:{
async setRightDialog(role) { this.roleId = role.id ...},
// 点击为角色分配权限
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) {
this.$message.error("分配权限失败!")
}
this.$message.success("分配权限成功!")
this.getRolesList()
this.setRightDialogVisible = false
}
}
分配角色
1 渲染分配角色的对话框并请求角色列表数据
User.vue
<!-- 分配角色按钮 -->
<el-button @click="setRole(scope.row)"></el-button>
<!-- 分配角色的对话框 -->
<el-dialog title="分配角色" :visible.sync="setRolesDialogVisible" width="50%">
<div>
<p>当前的用户:{{userInfo.username}}</p>
<p>当前的角色:{{userInfo.role_name}}</p>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="setRolesDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="setRolesDialogVisible = false">确 定</el-button>
</span>
</el-dialog>
data() { return {
setRolesDialogVisible: false ,//控制分配角色对话框的显示与隐藏
userInfo:{}, // 需要被分配角色的用户信息
roleslist:[] // 角色数据列表
}
methods:{
async setRole(userInfo) {
// 获取角色列表
const {data:res} =await this.$http.get('roles')
if (res.meta.status != 200) {
return this.$message.error("获取角色列表失败!")
}
this.$message.success("获取角色列表成功!")
this.roleslist = res.data
this.userInfo = userInfo
this.setRolesDialogVisible = true
}
}
2 渲染角色列表的select下拉菜单
<p>分配新角色:
<el-select v-model="selectRoleId" placeholder="请选择">
<el-option v-for="item in roleslist" :key="item.id" :label="item.roleName" :value="item.id"> </el-option>
</el-select>
</p>
data() {return { selectRoleId: ""} } // 已选中的角色id值
//element.js
import { Select,Option } from 'element-ui'
Vue.use(Select)
Vue.use(Option)
3 完成分配角色的功能
<!-- 分配角色的对话框 -->
<el-dialog @close='setRoleDialogClosed'>
<el-button type="primary" @click="saveRoleInfo">确 定</el-button>
methods:{
// 点击按钮,分配角色
async saveRoleInfo() {
if(!this.selectRoleId){ return this.$message.error('请选择要分配的角色!') }
const { data: res } = await this.$http.put(`users/${this.userInfo.id}/role`,{rid:this.selectRoleId})
if (res.meta.status != 200) {
return this.$message.error("更新角色失败!")
}
this.$message.success("更新角色成功!")
this.getUserList()
this.setRolesDialogVisible = false
},
// 监听分配角色对话框关闭事件
setRoleDialogClosed() {
this.selectRoleId = ''
this.userInfo = {}
}
}
提交到码云
(本地,云端已有 rights 分支)
本篇笔记最开始的位置
git branch #(master)
git checkout -b rights
git branch #(rights)
git push -u origin rights
本篇笔记完成