角色管理模块
角色管理介绍
目标:不同的用户登录系统后,能够操作不同的菜单。
总结:角色的增删改查
- 用户(员工)账号:用来登录系统
- 角色:员工的身份,不同的身份拥有不同的菜单,角色可以分配给用户
- 权限:功能按钮,可以分配给角色
总结:不同的用户登录系统后可以操作不同的菜单
角色管理组件布局
根据以上的结构,我们采用element-ui的组件实现**
src/views/setting/index.vue
**
<template>
<div class="setting-container">
<div class="app-container">
<el-card>
<el-tabs>
<!-- 左侧 -->
<el-tab-pane label="角色管理">
<!-- 按钮 -->
<el-button
icon="el-icon-plus"
size="small"
type="primary"
>新增角色</el-button>
<!-- 表格 -->
<el-table>
<el-table-column label="序号" width="100" />
<el-table-column label="角色名称" width="240" />
<el-table-column label="描述" />
<el-table-column label="操作">
<el-button size="small" type="success">分配权限</el-button>
<el-button size="small" type="primary">编辑</el-button>
<el-button size="small" type="danger">删除</el-button>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="公司信息">
<!-- 公司信息 -->
</el-tab-pane>
</el-tabs>
</el-card>
</div>
</div>
</template>
总结:
- 卡片组件 el-card
- 选项卡组件用法 el-tabs
- 表格组件的用法 el-table
获取角色列表数据
- 首先,封装读取角色的信息的请求
src/api/setting.js
import request from '@/utils/request'
/**
* 获取角色列表
* ***/
export function reqGetRoleList(options) {
return request({
method: 'get',
url: '/sys/role',
data: options
})
}
- 然后,在页面中调用接口获取数据
src/views/setting/index.vue
import { reqGetRoleList } from '@/api/setting.js'
export default {
name: 'Setting',
data () {
return {
// 查询参数
fillterParams: {
page: 1,
pagesize: 10
},
// 角色列表
list: [],
// 角色列表的总数
total: 0
}
},
created () {
this.loadRoleList()
},
methods: {
// 加载角色列表的数据
async loadRoleList () {
try {
const ret = await reqGetRoleList(this.fillterParams)
this.list = ret.data.rows
this.total = ret.data.total
} catch {
this.$message.error('获取角色列表失败')
}
}
}
}
- 绑定表格数据
<el-table :data="list">
<el-table-column type="index" label="序号" width="120" />
<el-table-column prop="name" label="角色名称" width="240" />
<el-table-column prop="description" label="描述" />
<el-table-column label="操作">
<el-button size="small" type="success">分配权限</el-button>
<el-button size="small" type="primary">编辑</el-button>
<el-button size="small" type="danger">删除</el-button>
</el-table-column>
</el-table>
总结:调用接口;获取数据;渲染表格
注意:表格列的索引
type='index'
是ElementUI提供的规则注意:分页方式基于页码和每页条数
处理表格分页
需求:基于ElementUI提供的分页组件实现分页
<el-pagination
layout="prev, pager, next"
:total="total"
:current-page="page"
:page-size="pagesize"
@current-change="changePage"
/>
// 控制页码的变化
changePage (page) {
// page表示当前页码
this.queryData.page = page
this.loadRoleList()
},
总结:分页的本质,根据当前的页码的变化,重新加载当前页的数据,并且把之前的数据覆盖了
- 控制每页条数的切换 sizes @size-change
- 控制跳转到第几页 jumper
- 显示总条数 total
- --> 用于控制布局(左右布局)
- slot 用于自定义模板
处理序号问题
- 自定义序号
<el-table-column type="index" :index="handleIndex" label="序号" width="120" />
- 配置自定义函数
methods: {
handleIndex (index) {
// 形参index表示列表数据的索引,从0开始
// 动态计算累加的索引
// (当前页码 - 1) * 每页的条数
const { page, pagesize } = this.filterParams
return (page - 1) * pagesize + 1 + index
},
}
总结:动态计算索引的累加值
- 表格列组件提供的index属性绑定一个函数,用于动态计算索引
- 基于分页参数计算连续的索引值
添加表格loading效果
- 绑定加载状态位
<el-table v-loading="loading" :data="list">
data () {
return {
loading: false
}
}
- 动态设置 loading 的状态
// 获取角色列表数据
async loadRoleList () {
try {
this.loading = true
const ret = await reqGetRoleList(this.queryData)
if (ret.code === 10000) {
this.list = ret.data.rows
this.total = ret.data.total
}
} catch {
this.$message.error('获取角色列表失败')
} finally {
this.loading = false
}
}
总结:通过v-loading绑定表格的加载状态,接口调用之前显示加载状态,接口数据返回后隐藏状态。
删除角色功能
目标
实现删除角色的功能
- 绑定事件
- 提示删除
- 调用接口实现删除
- 刷新列表
- 封装删除角色的api
export function reqDeleteRole(id) {
return request({
url: `/sys/role/${id}`,
method: 'delete'
})
}
- 删除按钮注册事件
<el-table-column label="操作">
<template #default="{ row }">
<el-button size="small" type="success">分配权限</el-button>
<el-button size="small" type="primary">编辑</el-button>
<el-button size="small" type="danger" @click="delRole(row.id)">删除</el-button>
</template>
</el-table-column>
- 删除功能实现
// 删除角色
handleDelete (id) {
// 删除前进行提示
this.$confirm('确认要删除角色吗?, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
// 点击确定
const ret = await reqDeleteRole(id)
// 删除角色成功,刷新列表
if (ret.code === 10000) {
this.loadRoleList()
} else {
this.$message.error(ret.message)
}
}).catch((err) => {
if (err !== 'cancel') {
// 点击取消
this.$message.error('删除角色失败')
}
})
}
// ----------------------------------------
// 删除操作
async handleDel (id) {
const ret = await this.$confirm('确认要删除吗', '提示', {
type: 'warning'
}).catch(err => err)
// 点击取消
if (ret === 'cancel') return
// 点击确定
try {
const delRet = await reqDeleteRole(id)
if (delRet.code === 10000) {
// 删除成功,刷新列表
// 如果当前页面数据被删除完成了,刷新上一页数据
if (this.queryData.page > 1 && this.list.length === 1) {
// 页码需要大于1且当前页就剩一条数据
this.queryData.page -= 1
this.loadSettingList()
}
} else {
// 删除失败
this.$message.error('删除失败')
}
} catch {
this.$message.error('删除失败')
}
},
总结:绑定事件;调用接口;刷新列表
- 作用域插槽
- 提示方法的使用
注意:如果当前页面删除完了数据,那么就刷新上一页。
添加角色弹窗控制
添加角色流程
- 点击添加按钮绑定事件
- 显示弹窗
- 实现表单,添加表单验证
- 提交表单
- 刷新列表
- 准备弹框
<el-dialog title="弹层标题" :visible.sync="isShowAddBox">
我是弹层
</el-dialog>
// data中添加一个状态位
isShowAddBox: false
- 给按钮注册点击事件
<el-button
icon="el-icon-plus"
size="small"
type="primary"
@click="isShowAddBox=true"
>新增角色</el-button>
- 准备弹框表单结构
<el-dialog title="弹层标题" :visible="showDialog" @close="btnCancel">
<el-form ref="roleForm" :model="form" :rules="rules" label-width="100px">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" placeholder="请输入角色名称" />
</el-form-item>
<el-form-item label="角色描述">
<el-input v-model="form.description" placeholder="请输入角色描述" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="btnCancel">取消</el-button>
<el-button type="primary">确认</el-button>
</template>
</el-dialog>
- 准备数据 - 注意: 这边接口文档字段有误, 是
name
和description
data() {
return {
...
form: {
name: '',
description: ''
},
rules: {
name: [
{ required: true, message: '请输入角色名称', trigger: ['blur', 'change'] }
]
}
}
},
总结
- 表单的角色描述的名称和接口文档不一致(接口文档有误)
- 表单验证
添加角色提交表单
步骤:
- 准备接口
- 表单验证
- 触发接口调用
- 刷新列表
- 封装新增角色功能api
setting.js
export function reqAddRole(data) {
return request({
url: '/sys/role',
data,
method: 'post'
})
}
- 校验完成添加功能
<el-button type="primary" @click="handleSubmit">确认</el-button>
// 添加角色提交表单
async handleSubmit () {
// 添加角色,提交表单
try {
const ret = await reqAddRole(this.form)
if (ret.code === 10000) {
// 添加成功,关闭弹窗,属性列表
this.isShowAddBox = false
this.loadRoleList()
} else {
this.$message.error('添加角色失败')
}
} catch {
this.$message.error('添加角色失败')
}
},
总结:封装接口;绑定事件;验证表单;调用接口
- 重置表单的用法
- 重置表单的方法
resetFields
需要表单项有prop才可以 - 也可以通过
this.$options.data()
的方式获取表单的原始数据
- 重置表单的方法
// 取消操作
handleCancel () {
// 隐藏弹窗
this.showDialog = false
// this.$refs.roleForm.resetFields()
// this.$options.data()表示data中的原始数据
// 重置表单
this.form = this.$options.data().form
},
总结:重置表单
- 直接调用表单组件的resetFields方法,可以重置验证提示信息
- 也可以借助this.$options.data()方式重置表单,不可以重置验证提示信息
编辑角色封装接口
编辑角色:
- 点击按钮加载角色的数据并且回填表单
- 修改信息后提交表单
- 封装接口
// 修改角色
export function reqUpdateRole(data) {
return request({
method: 'put',
url: `/sys/role/${data.id}`,
data
})
}
// 获取角色详情
export function reqGetRoleDetail(id) {
return request({
method: 'get',
url: `/sys/role/${id}`
})
}
编辑角色显示数据
- 点击编辑按钮
<el-button size="small" type="primary" @click="handleEdit(row.id)">编辑</el-button>
- 显示弹层, 获取数据回显
import { reqAddRole, reqDeleteRole, reqGetRoleDetail, reqGetRoleList } from '@/api/setting'
// 编辑显示弹窗
async handleEdit (id) {
try {
// 根据id获取该角色的信息,填充表单
const ret = await reqGetRoleDetail(id)
if (ret.code === 10000) {
this.form = ret.data
// 显示弹窗
this.isShowAddBox = true
}
} catch {
this.$message.error('获取角色信息失败')
}
},
- 计算属性 - 控制标题
computed: {
title() {
return this.form.id ? '编辑角色' : '添加角色'
}
},
- 编辑完成
// 添加角色提交表单
async handleSubmit () {
// 添加橘色和编辑角色提交表单
if (this.form.id) {
// 编辑角色
try {
const ret = await reqUpdateRole(this.form)
if (ret.code === 10000) {
// 编辑成功,关闭弹窗,刷新列表
this.isShowAddBox = false
this.loadRoleList()
}
} catch {
this.$message.error('编辑角色失败')
}
} else {
// 添加角色
try {
const ret = await reqAddRole(this.form)
if (ret.code === 10000) {
// 添加成功,关闭弹窗,刷新列表
this.isShowAddBox = false
this.loadRoleList()
}
} catch {
this.$message.error('添加角色失败')
}
}
},
总结:添加和编辑角色重用提交逻辑(通过表单数据的id存在与否区分两种操作)