笔记来源:拉勾教育 - 大前端就业集训营
文章内容:学习过程中的笔记、感悟、和经验
角色管理
基础布局、数据展示、列表展示、删除功能和以前一样,可以课下联系练习
角色管理分析和准备工作
和资源管理一样,新建子组件,把结构书写在子组件中
结构上面为表单,下面为列表和添加按钮
如果双标签里面没有内容,那么可以直接写成< />
使用按条件查询接口,这样可以把筛选功能也一起处理
删除角色使用删除角色接口
设置加载中处理
时间处理
src/views/role/index.vue
<template>
<!-- 创建子组件 -->
<Content/>
</template>
<script>
// 引入子组件
import Content from './son/content.vue'
export default {
name: 'role',
// 注册子组件
components: {
Content
}
}
</script>
src/views/role/son/content.vue
<template>
<!-- 外层容器 -->
<el-card class="box-card">
<!-- 头部 -->
<div slot="header" class="clearfix">
<!-- 表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="角色名称">
<el-input v-model="formInline.user" placeholder="角色名称"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">查询</el-button>
</el-form-item>
<el-form-item>
<el-button>重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 表格 -->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="id"
label="编号">
</el-table-column>
<el-table-column
prop="name"
label="角色名称">
</el-table-column>
<el-table-column
prop="description"
label="描述">
</el-table-column>
<el-table-column
label="添加时间">
<template slot-scope="scope">
<!-- 使用过滤器过滤插槽数据 -->
<span>{{scope.row.createdTime | time}}</span>
</template>
</el-table-column>
<el-table-column
prop="address"
label="操作"
width="180">
<template slot-scope="scope">
<!-- 编辑按钮 -->
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<!-- 删除按钮,添加事件 -->
<el-button
size="mini"
type="danger"
@click="roleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</template>
<script>
// 引入按条件查询角色、删除角色
import { getRolePages, deleteRole } from '@/services/role'
export default {
data () {
return {
formInline: {
},
// 表格数据
tableData: []
}
},
// 生命周期钩子函数
created () {
// 获取数据,使用控对象作为参数
this.getRole({})
},
// 方法
methods: {
// 获取角色
async getRole (obj) {
const { data } = await getRolePages(obj)
if (data.code === '000000') {
// 获取成功将数据交给表格进行渲染
this.tableData = data.data.records
}
},
// 删除角色
async roleDelete (id) {
const { data } = await deleteRole(id)
if (data.code === '000000') {
// 如果删除成功,弹出提示消息,并且重新渲染
this.$message({
message: '删除成功',
type: 'success'
})
this.getRole({})
}
}
},
// 过滤器
filters: {
// 时间格式过滤器
time (data) {
data = new Date()
return `${data.getFullYear()}/${data.getMonth()}/${data.getDay()} ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
}
}
}
</script>
// src/services/role.js
// 引入接口模块
import request from '@/utils/request'
// 按条件查询角色
export const getRolePages = data => {
return request({
method: 'post',
url: '/boss/role/getRolePages',
data
})
}
// 删除角色
export const deleteRole = id => {
return request({
method: 'delete',
url: `/boss/role/${id}`
})
}
添加角色布局
点击添加按钮弹出对话框组件,在内部设置功能
对话框内部创建一个新组件,把功能模块写在新组件中,当然添加和编辑是一样的结构,可以共用一个组件
src/views/role/son/content.vue
<template>
<!-- 外层容器 -->
<el-card class="box-card">
<!-- 头部 -->
<div slot="header" class="clearfix">
<!-- 表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="角色名称">
<el-input v-model="formInline.user" placeholder="角色名称"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">查询</el-button>
</el-form-item>
<el-form-item>
<el-button>重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 添加角色按钮,添加点击事件 -->
<el-button @click="addRole">添加角色</el-button>
<!-- 表格 -->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="id"
label="编号">
</el-table-column>
<el-table-column
prop="name"
label="角色名称">
</el-table-column>
<el-table-column
prop="description"
label="描述">
</el-table-column>
<el-table-column
label="添加时间">
<template slot-scope="scope">
<!-- 使用过滤器过滤插槽数据 -->
<span>{{scope.row.createdTime | time}}</span>
</template>
</el-table-column>
<el-table-column
prop="address"
label="操作"
width="180">
<template slot-scope="scope">
<!-- 编辑按钮 -->
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<!-- 删除按钮,添加事件 -->
<el-button
size="mini"
type="danger"
@click="roleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 创建子组件实例,传递参数show,设置自定义事件 -->
<Dialog :show="centerDialogVisible" @unShow="unShow"/>
</el-card>
</template>
<script>
// 引入按条件查询角色、删除角色
import { getRolePages, deleteRole } from '@/services/role'
// 引入组件
import Dialog from './dialog'
export default {
data () {
return {
formInline: {
},
// 表格数据
tableData: [],
// 对话框信号值,ture显示,false隐藏
centerDialogVisible: false
}
},
// 生命周期钩子函数
created () {
// 获取数据,使用控对象作为参数
this.getRole({})
},
// 方法
methods: {
// 修改信号值隐藏对话框
unShow () {
this.centerDialogVisible = false
},
// 添加角色按钮事件
addRole () {
this.centerDialogVisible = true
},
// 获取角色
async getRole (obj) {
const { data } = await getRolePages(obj)
if (data.code === '000000') {
// 获取成功将数据交给表格进行渲染
this.tableData = data.data.records
}
},
// 删除角色
async roleDelete (id) {
const { data } = await deleteRole(id)
if (data.code === '000000') {
// 如果删除成功,弹出提示消息,并且重新渲染
this.$message({
message: '删除成功',
type: 'success'
})
this.getRole({})
}
}
},
// 过滤器
filters: {
// 时间格式过滤器
time (data) {
data = new Date()
return `${data.getFullYear()}/${data.getMonth()}/${data.getDay()} ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
}
},
// 注册组件
components: {
Dialog
}
}
</script>
src/views/role/son/dialog.vue - 新建子组件
<template>
<!-- 对话框,绑定show -->
<el-dialog
title="提示"
:visible.sync="show"
width="30%"
center
>
<el-form :model="formLabelAlign">
<el-form-item label="角色名称">
<el-input v-model="formLabelAlign.name"></el-input>
</el-form-item>
<el-form-item label="角色编码">
<el-input v-model="formLabelAlign.code"></el-input>
</el-form-item>
<el-form-item label="角色描述">
<el-input v-model="formLabelAlign.description"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<!-- 确定和取消按钮绑定事件 -->
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="confirm"
>确 定</el-button
>
</span>
</el-dialog>
</template>
<script>
export default {
// 父组件传递的参数
props: ['show'],
data () {
return {
// 对话框内部组件数据
formLabelAlign: {}
}
},
methods: {
// 确定按钮点击事件函数
confirm () {
this.$emit('unShow')
console.log('确定')
},
// 取消按钮点击事件函数
cancel () {
// 触发子组件自定义事件
this.$emit('unShow')
console.log('取消')
}
}
}
</script>
添加角色功能实现
使用保存或更新角色接口
添加角色之后要关闭提示框,需要使用子向父通信
清空表单,直接设置空空即可
确认后刷新列表
取消按钮直接关闭,但是不更新数据,清空表单内容
// src/services/role.js
// 更新或保存角色
export const saveOrUpdate = data => {
return request({
method: 'post',
url: '/boss/role/saveOrUpdate',
data
})
}
src/views/role/son/content.vue
<template>
<!-- 外层容器 -->
<el-card class="box-card">
<!-- 头部 -->
<div slot="header" class="clearfix">
<!-- 表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="角色名称">
<el-input v-model="formInline.user" placeholder="角色名称"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">查询</el-button>
</el-form-item>
<el-form-item>
<el-button>重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 添加角色按钮,添加点击事件 -->
<el-button @click="addRole">添加角色</el-button>
<!-- 表格 -->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="id"
label="编号">
</el-table-column>
<el-table-column
prop="name"
label="角色名称">
</el-table-column>
<el-table-column
prop="description"
label="描述">
</el-table-column>
<el-table-column
label="添加时间">
<template slot-scope="scope">
<!-- 使用过滤器过滤插槽数据 -->
<span>{{scope.row.createdTime | time}}</span>
</template>
</el-table-column>
<el-table-column
prop="address"
label="操作"
width="180">
<template slot-scope="scope">
<!-- 编辑按钮 -->
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<!-- 删除按钮,添加事件 -->
<el-button
size="mini"
type="danger"
@click="roleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 创建子组件实例,传递参数show,设置自定义事件 -->
<Dialog :show="centerDialogVisible" @unShow="unShow" @upDate="getRole"/>
</el-card>
</template>
<script>
// 引入按条件查询角色、删除角色
import { getRolePages, deleteRole } from '@/services/role'
// 引入组件
import Dialog from './dialog'
export default {
data () {
return {
formInline: {
},
// 表格数据
tableData: [],
// 对话框信号值,ture显示,false隐藏
centerDialogVisible: false
}
},
// 生命周期钩子函数
created () {
// 获取数据,使用控对象作为参数
this.getRole({})
},
// 方法
methods: {
// 修改信号值隐藏对话框
unShow () {
this.centerDialogVisible = false
},
// 添加角色按钮事件
addRole () {
this.centerDialogVisible = true
},
// 获取角色
async getRole (obj) {
const { data } = await getRolePages(obj)
if (data.code === '000000') {
// 获取成功将数据交给表格进行渲染
this.tableData = data.data.records
}
},
// 删除角色
async roleDelete (id) {
const { data } = await deleteRole(id)
if (data.code === '000000') {
// 如果删除成功,弹出提示消息,并且重新渲染
this.$message({
message: '删除成功',
type: 'success'
})
this.getRole({})
}
}
},
// 过滤器
filters: {
// 时间格式过滤器
time (data) {
data = new Date()
return `${data.getFullYear()}/${data.getMonth()}/${data.getDay()} ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
}
},
// 注册组件
components: {
Dialog
}
}
</script>
src/views/role/son/dialog.vue
<template>
<!-- 对话框,绑定show -->
<el-dialog
title="提示"
:visible.sync="show"
width="30%"
center
>
<el-form :model="formLabelAlign">
<el-form-item label="角色名称">
<el-input v-model="formLabelAlign.name"></el-input>
</el-form-item>
<el-form-item label="角色编码">
<el-input v-model="formLabelAlign.code"></el-input>
</el-form-item>
<el-form-item label="角色描述">
<el-input v-model="formLabelAlign.description"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<!-- 确定和取消按钮绑定事件 -->
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="confirm"
>确 定</el-button
>
</span>
</el-dialog>
</template>
<script>
// 引入更新或保存角色
import { saveOrUpdate } from '@/services/role'
export default {
// 父组件传递的参数
props: ['show'],
data () {
return {
// 对话框内部组件数据
formLabelAlign: {}
}
},
methods: {
// 确定按钮点击事件函数
async confirm () {
// 判断必填项是否为空
if (this.formLabelAlign.name && this.formLabelAlign.code) {
// 如果必填项不为空获取数据
const { data } = await saveOrUpdate(this.formLabelAlign)
if (data.code === '000000') {
// 如果添加或者保存成功弹出提示
this.$message({
message: '保存角色成功',
type: 'success'
})
// 触发自定义事件,清空数据
this.$emit('unShow')
this.formLabelAlign = {}
this.$emit('upDate')
}
} else {
// 提示必填项必填
this.$message.error('角色名称和编码是必填项哦')
}
},
// 取消按钮点击事件函数
cancel () {
// 触发子组件自定义事件
this.$emit('unShow')
// 清空数据
this.formLabelAlign = {}
}
}
}
</script>
编辑角色
编辑角色和添加角色使用同一个对话框,所以我们需要创建一个信号量标记当前是编辑还是添加,子组件接收数据判断是否需要拉去编辑的数据(我认为可以直接判断是否有传入参数,如果传入了参数就代表编辑)
使用获取角色接口
// src/services/role.js
// 引入接口模块
import request from '@/utils/request'
// 按条件查询角色
export const getRolePages = (data = {}) => {
return request({
method: 'post',
url: '/boss/role/getRolePages',
data
})
}
// 删除角色
export const deleteRole = id => {
return request({
method: 'delete',
url: `/boss/role/${id}`
})
}
// 更新或保存角色
export const saveOrUpdate = data => {
return request({
method: 'post',
url: '/boss/role/saveOrUpdate',
data
})
}
// 获取角色信息
export const getRole = id => {
return request({
method: 'get',
url: `/boss/role/${id}`
})
}
src/views/role/son/content.vue
<template>
<!-- 外层容器 -->
<el-card class="box-card">
<!-- 头部 -->
<div slot="header" class="clearfix">
<!-- 表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="角色名称">
<el-input v-model="formInline.user" placeholder="角色名称"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">查询</el-button>
</el-form-item>
<el-form-item>
<el-button>重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 添加角色按钮,添加点击事件 -->
<el-button @click="addRole">添加角色</el-button>
<!-- 表格 -->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="id"
label="编号">
</el-table-column>
<el-table-column
prop="name"
label="角色名称">
</el-table-column>
<el-table-column
prop="description"
label="描述">
</el-table-column>
<el-table-column
label="添加时间">
<template slot-scope="scope">
<!-- 使用过滤器过滤插槽数据 -->
<span>{{scope.row.createdTime | time}}</span>
</template>
</el-table-column>
<el-table-column
prop="address"
label="操作"
width="180">
<template slot-scope="scope">
<!-- 编辑按钮 -->
<el-button
size="mini"
@click="handleEdit(scope.row.id)">编辑</el-button>
<!-- 删除按钮,添加事件 -->
<el-button
size="mini"
type="danger"
@click="roleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 创建子组件实例,传递参数show,设置自定义事件 -->
<Dialog :show="centerDialogVisible" :getId="getId" @reset="reset" @upDate="getRole"/>
</el-card>
</template>
<script>
// 引入按条件查询角色、删除角色
import { getRolePages, deleteRole } from '@/services/role'
// 引入组件
import Dialog from './dialog'
export default {
data () {
return {
formInline: {
},
// 表格数据
tableData: [],
// 对话框信号值,ture显示,false隐藏
centerDialogVisible: false,
// 信号值:当前需要编辑的角色id,默认为0
getId: 0
}
},
// 生命周期钩子函数
created () {
// 获取数据,使用控对象作为参数
this.getRole({})
},
// 方法
methods: {
// 编辑按钮事件
handleEdit (id) {
// 修改信号值
this.getId = id
this.centerDialogVisible = true
},
// 组件自定义事件函数,重置信号值
reset () {
this.centerDialogVisible = false
this.getId = 0
},
// 添加角色按钮事件
addRole () {
this.centerDialogVisible = true
},
// 获取角色
async getRole (obj) {
const { data } = await getRolePages(obj)
if (data.code === '000000') {
// 获取成功将数据交给表格进行渲染
this.tableData = data.data.records
}
},
// 删除角色
async roleDelete (id) {
const { data } = await deleteRole(id)
if (data.code === '000000') {
// 如果删除成功,弹出提示消息,并且重新渲染
this.$message({
message: '删除成功',
type: 'success'
})
this.getRole()
}
}
},
// 过滤器
filters: {
// 时间格式过滤器
time (data) {
data = new Date()
return `${data.getFullYear()}/${data.getMonth()}/${data.getDay()} ${data.getHours()}:${data.getMinutes()}:${data.getSeconds()}`
}
},
// 注册组件
components: {
Dialog
}
}
</script>
src/views/role/son/dialog.vue
<template>
<!-- 对话框,绑定show,禁止关闭按钮和点击消失 -->
<el-dialog
title="角色"
:visible.sync="show"
width="30%"
center
:show-close="false"
:close-on-click-modal="false"
>
<el-form :model="formLabelAlign">
<el-form-item label="角色名称">
<el-input v-model="formLabelAlign.name"></el-input>
</el-form-item>
<el-form-item label="角色编码">
<el-input v-model="formLabelAlign.code"></el-input>
</el-form-item>
<el-form-item label="角色描述">
<el-input v-model="formLabelAlign.description"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<!-- 确定和取消按钮绑定事件 -->
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="confirm"
>确 定</el-button
>
</span>
</el-dialog>
</template>
<script>
// 引入更新或保存角色
import { saveOrUpdate, getRole } from '@/services/role'
export default {
// 父组件传递的参数
props: ['show', 'getId'],
data () {
return {
// 对话框内部组件数据
formLabelAlign: {}
}
},
methods: {
// 获取需要编辑的角色数据
async getInfo (id) {
if (id !== 0) {
// 如果传入的角色id不是0,获取角色数据,否则不获取数据
const { data } = await getRole(id)
if (data.code === '000000') {
this.formLabelAlign = data.data
}
}
},
// 确定按钮点击事件函数
async confirm () {
// 判断必填项是否为空
if (this.formLabelAlign.name && this.formLabelAlign.code) {
// 如果必填项不为空获取数据
const { data } = await saveOrUpdate(this.formLabelAlign)
if (data.code === '000000') {
// 如果添加或者保存成功弹出提示
this.$message({
message: '保存角色成功',
type: 'success'
})
// 触发自定义事件,清空数据
this.$emit('reset')
this.formLabelAlign = {}
this.$emit('upDate')
}
} else {
// 提示必填项必填
this.$message.error('角色名称和编码是必填项哦')
}
},
// 取消按钮点击事件函数
cancel () {
// 触发子组件自定义事件
this.$emit('reset')
// 清空数据
this.formLabelAlign = {}
}
},
// 侦听器
watch: {
// 侦听show,一旦show为true,立马调用函数
show (newvalue) {
if (newvalue) {
this.getInfo(this.getId)
}
}
}
}
</script>
分配菜单布局
分配菜单功能使用独立页面,所以在角色管理下同级别创建页面
路由添加新路由
点击分配菜单跳转到页面,带参数跳转
这里按照平常的方法就不适合作为组件使用,所以使用路径路由传参的方式进行参数传递(路由中设置props:true,组件使用props获取)设置参数必须(required:true)
// src/router/index.js
{
// 分配菜单
name: 'AssignmentMenu',
path: '/role/AssignmentMenu/:id',
component: () => import(/* webpackChunkName:'role' */ '@/views/role/assignmentMenu'),
// 设置路径参数
props: true
}
src/views/role/son/content.vue,添加分配菜单和资源按钮,设置点击跳转到分配页
.........
<!-- 分配菜单按钮 -->
<el-button type="text" @click="assignmentMenu(scope.row.id)">分配菜单</el-button>
<!-- 分配资源按钮 -->
<el-button type="text">分配资源</el-button>
<!-- 编辑按钮 -->
.............
// 分配菜单按钮点击事件函数
assignmentMenu (id) {
// 带参数跳转
this.$router.push({
name: 'AssignmentMenu',
params: {
id
}
})
}
src/views/role/assignmentMenu.vue,新建独立组件,在内部书写分配页
<template>
<div>fenpeicaidan </div>
</template>
<script>
export default {
// 直接使用路径参数
props: ['id'],
created () {
console.log(this.id)
}
}
</script>
分配菜单列表展示
使用element树形控件
修改可勾选,默认展开
使用获取所有菜单并按层级展示接口
在页面加载的时候获取所有菜单,直接把接收到的数据设置到data,修改对应关系即可
src/services/menu.js
// 获取所有菜单并按层级展示
export const getMenuNodeList = () => {
return request({
method: 'get',
url: '/boss/menu/getMenuNodeList'
})
}
src/views/role/assignmentMenu.vue,新建文件展示菜单分配页面
<template>
<el-card>
<!-- 树形控件,设置可选择,默认展开 -->
<el-tree
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
default-expand-all
show-checkbox/>
</el-card>
</template>
<script>
// 引入 获取全部菜单层级
import { getMenuNodeList } from '@/services/menu'
export default {
data () {
return {
// 树形控件数据
data: [],
// 对应关系
defaultProps: {
children: 'subMenuList',
label: 'name'
}
}
},
// 钩子函数
created () {
// 调用方法获取全部层级
this.getList()
},
methods: {
handleNodeClick (data) {
console.log(data)
},
// 获取全部菜单层级
async getList () {
const { data } = await getMenuNodeList()
if (data.code === '000000') {
// 获取成功将全部层级数据交给树形控件
this.data = data.data
}
}
}
}
</script>
分配菜单保存
添加保存和清空按钮
使用给角色分配菜单接口
树形控件提供了方法,可以返回全部选中的数组(使用refs设置),给数分配一个node-key的属性可以把id绑定给节点
保存跳转回页面
// src/services/menu.js
// 给角色分配菜单
export const allocateRoleMenus = data => {
return request({
method: 'post',
url: '/boss/menu/allocateRoleMenus',
data
})
}
src/views/role/assignmentMenu.vue
<template>
<el-card>
<!-- 树形控件,设置可选择,默认展开,ref、node-key-->
<el-tree
ref="tree"
node-key="id"
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
default-expand-all
show-checkbox/>
<div style="margin: 20px">
<el-button>清空</el-button>
<el-button type="primary" @click="preservation">保存</el-button>
</div>
</el-card>
</template>
<script>
// 引入 获取全部菜单层级,分配菜单保存a
import { getMenuNodeList, allocateRoleMenus } from '@/services/menu'
export default {
// 参数
props: ['id'],
// 命名
name: 'assignment',
data () {
return {
// 树形控件数据
data: [],
// 对应关系
defaultProps: {
children: 'subMenuList',
label: 'name'
},
// 保存传递参数
user: {
roleId: '',
menuIdList: []
}
}
},
// 钩子函数
created () {
// 调用方法获取全部层级
this.getList()
},
methods: {
// 保存按钮事件函数
async preservation () {
// 设置需要上传的参数
this.user.menuIdList = this.$refs.tree.getCheckedKeys()
this.user.roleId = this.id
// 调用接口
const { data } = await allocateRoleMenus(this.user)
if (data.code === '000000') {
// 如果操作成功,弹出提示。返回角色列表页面
this.$message({
message: '保存成功',
type: 'success'
})
this.$router.push('/role')
}
},
// 获取全部菜单层级
async getList () {
const { data } = await getMenuNodeList()
if (data.code === '000000') {
// 获取成功将全部层级数据交给树形控件
this.data = data.data
}
}
}
}
</script>
分配菜单展示优化改进
跳转分配菜单功能需要展示当前角色已经分配的菜单
使用获取角色拥有的菜单列表接口
在创建组件的时候自动更换获取已经拥有的菜单
筛选全部选中的菜单id组成数组,如果节点内部还有子节点,那么这个id不需要取出(这里使用递归)
使用树形控件属性可以控制那些节点默认勾选,把数组传递进来
src/views/role/assignmentMenu.vue
<template>
<el-card>
<!-- 树形控件,设置可选择,默认展开,ref、node-key,设置默认勾选菜单-->
<el-tree
:default-checked-keys="defaultCheckedKeys"
ref="tree"
node-key="id"
:data="data"
:props="defaultProps"
default-expand-all
show-checkbox/>
<div style="margin: 20px">
<el-button>清空</el-button>
<el-button type="primary" @click="preservation">保存</el-button>
</div>
</el-card>
</template>
<script>
// 引入 获取全部菜单层级,分配菜单保存,获取用户已拥有菜单
import { getMenuNodeList, allocateRoleMenus, getRoleMenus } from '@/services/menu'
export default {
// 参数
props: ['id'],
// 命名
name: 'assignment',
data () {
return {
// 树形控件数据
data: [],
// 对应关系
defaultProps: {
children: 'subMenuList',
label: 'name'
},
// 保存传递参数
user: {
roleId: '',
menuIdList: []
},
// 用户已拥有菜单id数组
defaultCheckedKeys: []
}
},
// 钩子函数
created () {
// 调用方法获取全部层级
this.getList()
// 获取已拥有菜单
this.getUserMenu()
},
methods: {
// 遍历全部数组筛选选中的菜单
screenMenu (data) {
// 遍历数组
data.forEach(item => {
// 如果selected为false,直接返回
if (!item.selected) {
return
}
// 如果还有子列表,递归调用
if (item.subMenuList) {
return this.screenMenu(item.subMenuList)
}
// 如果值为true并且没有子菜单,则将id添加到数组中(这里使用ed6语法,因为push会导致不显示)
this.defaultCheckedKeys = [...this.defaultCheckedKeys, item.id]
})
},
// 获取用户拥有的菜单
async getUserMenu () {
// 调用接口获取数据
const { data } = await getRoleMenus(this.id)
if (data.code === '000000') {
// 如果获取数据成功否,调用遍历方法获取全部已拥有菜单
this.screenMenu(data.data)
}
},
// 保存按钮事件函数
async preservation () {
// 设置需要上传的参数
this.user.menuIdList = this.$refs.tree.getCheckedKeys()
this.user.roleId = this.id
// 调用接口
const { data } = await allocateRoleMenus(this.user)
if (data.code === '000000') {
// 如果操作成功,弹出提示。返回角色列表页面
this.$message({
message: '保存成功',
type: 'success'
})
this.$router.push('/role')
}
},
// 获取全部菜单层级
async getList () {
const { data } = await getMenuNodeList()
if (data.code === '000000') {
// 获取成功将全部层级数据交给树形控件
this.data = data.data
}
}
}
}
</script>
分配菜单清空
点击清空直接使用树形控件的清空方法即可setCheckedKeys
src/views/role/assignmentMenu.vue,在methods中添加方法
................
// 清空勾选列表
empty () {
// 调用树形结构方法,传入空数组清空列表
this.$refs.tree.setCheckedKeys([])
},
..................
用户管理
分析与准备工作
筛选、展示和删除不在课程中操作,作为课后作业
使用日期选择器组件
使用分页查询用户信息接口
src/services/user.js
// 分页查询用户信息
export const getUserPages = data => {
return request({
method: 'post',
url: '/boss/user/getUserPages',
data
})
}
src/views/user/index.vue - 用户管理页面,引入子组件,将功能写在子组件中
<template>
<!-- 创建子组件实例 -->
<user-card></user-card>
</template>
<script>
// 引入子组件
import UserCard from './son/card'
export default {
name: 'user',
// 注册子组件
components: {
UserCard
}
}
</script>
src/views/user/son/card.vue
<template>
<!-- 容器 -->
<el-card class="box-card">
<!-- 卡片头部 -->
<div slot="header" class="clearfix">
<!-- form表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="手机号">
<el-input v-model="formInline.phone" placeholder="手机号"></el-input>
</el-form-item>
<!-- 日期选择器 -->
<el-form-item>
<el-date-picker
v-model="time"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"/>
</el-form-item>
<!-- 查询重置按钮,添加点击事件 -->
<el-form-item>
<el-button type="primary" @click="queryUser">查询</el-button>
<el-button @click="resetUser">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 表格 - 用户展示 -->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="id"
label="用户ID"/>
<el-table-column
label="头像">
<template slot-scope="scope">
<!-- 头像使用数据并设置默认值 -->
<el-avatar size="medium" :src="scope.row.portrait || 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'"></el-avatar>
</template>
</el-table-column>
<el-table-column
prop="name"
label="用户名"/>
<el-table-column
prop="phone"
label="手机号"/>
<el-table-column
label="注册时间">
<template slot-scope="scope">
<!-- 注册时间使用过滤器过滤格式 -->
<span>{{scope.row.createTime | time}}</span>
</template>
</el-table-column>
<el-table-column
label="状态">
</el-table-column>
<el-table-column
label="分配角色">
<!-- 分配角色按钮 -->
<el-button type="text">分配角色</el-button>
</el-table-column>
</el-table>
</el-card>
</template>
<script>
// 引入 - 分页查询用户信息
import { getUserPages } from '@/services/user'
export default {
// 组件命名
name: 'userCard',
data () {
return {
// 接口查询用户信息数据
formInline: {
phone: null
},
// 日期选择器数据
time: '',
// 用户列表数据
tableData: []
}
},
// 钩子函数
created () {
// 初始化获取用户数据
this.getUser(this.formInline)
},
methods: {
// 重置按钮事件函数
resetUser () {
// 重置数据
this.time = []
this.formInline.phone = null
},
// 查询按钮事件函数
queryUser () {
// 根据是否选择日期传递不同的参数
if (this.time && this.time.length === 2) {
this.getUser({
phone: this.formInline.phone,
startCreateTime: this.time[0],
endCreateTime: this.time[1]
})
} else {
this.getUser(this.formInline)
}
},
// 获取用户数据
async getUser (obj) {
// 获取数据
const { data } = await getUserPages(obj)
if (data.code === '000000') {
// 如果获取成功,将数据交给列表
this.tableData = data.data.records
}
}
},
// 过滤器
filters: {
// 时间过滤器,用于过滤表格中的用户注册时间
time (data) {
// 直接截取前10位字符串
return data.slice(0, 10)
}
}
}
</script>
分配角色布局
使用对话框组件
使用下拉菜单组件(可多选)
src/views/user/son/card.vue - 添加静态布局(对话框+多选选择器)
<template>
<!-- 容器 -->
<el-card class="box-card">
<!-- 卡片头部 -->
<div slot="header" class="clearfix">
<!-- form表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="手机号">
<el-input v-model="formInline.phone" placeholder="手机号"></el-input>
</el-form-item>
<!-- 日期选择器 -->
<el-form-item>
<el-date-picker
v-model="time"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"/>
</el-form-item>
<!-- 查询重置按钮,添加点击事件 -->
<el-form-item>
<el-button type="primary" @click="queryUser">查询</el-button>
<el-button @click="resetUser">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 表格 - 用户展示 -->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="id"
label="用户ID"/>
<el-table-column
label="头像">
<template slot-scope="scope">
<!-- 头像使用数据并设置默认值 -->
<el-avatar size="medium" :src="scope.row.portrait || 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'"></el-avatar>
</template>
</el-table-column>
<el-table-column
prop="name"
label="用户名"/>
<el-table-column
prop="phone"
label="手机号"/>
<el-table-column
label="注册时间">
<template slot-scope="scope">
<!-- 注册时间使用过滤器过滤格式 -->
<span>{{scope.row.createTime | time}}</span>
</template>
</el-table-column>
<el-table-column
label="状态">
</el-table-column>
<el-table-column
label="分配角色">
<!-- 分配角色按钮 -->
<el-button type="text" @click="assignroles">分配角色</el-button>
</el-table-column>
</el-table>
<!-- 对话框 -->
<el-dialog
title="分配角色"
:visible.sync="dialogVisible"
width="50%">
<!-- 选择器,绑定数据,multiple开启多选 -->
<el-select v-model="roltList" multiple placeholder="选择要分配的角色">
<el-option
v-for="item in options"
:key="item.value"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<!-- 取消和确定按钮 -->
<span slot="footer" class="dialog-footer">
<el-button>取 消</el-button>
<el-button type="primary">确 定</el-button>
</span>
</el-dialog>
</el-card>
</template>
<script>
// 引入 - 分页查询用户信息
import { getUserPages } from '@/services/user'
export default {
// 组件命名
name: 'userCard',
data () {
return {
// 接口查询用户信息数据
formInline: {
phone: null
},
// 日期选择器数据
time: '',
// 用户列表数据
tableData: [],
// 信号值 - 控制对话框显示隐藏
dialogVisible: false,
// 选择器选项数据
options: [],
// 选择器选择结果
roltList: []
}
},
// 钩子函数
created () {
// 初始化获取用户数据
this.getUser(this.formInline)
},
methods: {
// 分配角色按钮事件函数
assignroles () {
this.dialogVisible = true
},
// 重置按钮事件函数
resetUser () {
// 重置数据
this.time = []
this.formInline.phone = null
},
// 查询按钮事件函数
queryUser () {
// 根据是否选择日期传递不同的参数
if (this.time && this.time.length === 2) {
this.getUser({
phone: this.formInline.phone,
startCreateTime: this.time[0],
endCreateTime: this.time[1]
})
} else {
this.getUser(this.formInline)
}
},
// 获取用户数据
async getUser (obj) {
// 获取数据
const { data } = await getUserPages(obj)
if (data.code === '000000') {
// 如果获取成功,将数据交给列表
this.tableData = data.data.records
}
}
},
// 过滤器
filters: {
// 时间过滤器,用于过滤表格中的用户注册时间
time (data) {
// 直接截取前10位字符串
return data.slice(0, 10)
}
}
}
</script>
展示角色列表
使用获取所有角色接口
// src/services/user.js - 封装获取所有可分配角色
// 获取所有用户可以分配的角色
export const getAllRole = () => {
return request({
method: 'get',
url: '/boss/role/all'
})
}
// src/views/user/son/card.vue - 修改分配按钮点击事件获取全部可分配角色数据
//分配角色按钮事件函数
async assignroles () {
// 显示对话框
this.dialogVisible = true
// 获取全部可分配角色列表
const { data } = await getAllRole()
if (data.code === '000000') {
// 将所有角色交给选择器
this.options = data.data
}
}
提交分配角色
点击分配关闭对话框
使用为用户分配角色接口
src/views/user/son/card.vue - 确定按钮添加事件,取消按钮事件函数直接写在行内(this.dialogVisible = false)
// 分配角色确定按钮点击事件
async PerformAssignmentRoles () {
// 调用接口为用户设置角色
const { data } = await allocateUserRoles({
userId: this.userId,
roleIdList: this.roltList
})
if (data.code === '000000') {
// 如果设置成功,弹出提示,并关闭对话框
this.$message({
message: '保存成功',
type: 'success'
})
this.dialogVisible = false
}
}
// src/services/user.js - 封装接口
// 给用户分配角色
export const allocateUserRoles = data => {
return request({
method: 'post',
url: '/boss/role/allocateUserRoles',
data
})
}
默认选中已分配角色
使用查询用户角色接口
自动查询当前用户有哪些角色
把角色分配给下拉菜单
// src/services/user.js
// 引入接口模块
import request from '@/utils/request'
// 引入qs插件
import qs from 'qs'
// 用户登录
// data为参数
export const login = (data) => {
// 使用接口模块
return request({
// post方法
method: 'post',
// 接口地址
url: '/front/user/login',
// 使用qs转换参数
data: qs.stringify(data)
})
}
// 用户信息获取模块
export const getUserInfo = () => {
return request({
// get方法
method: 'get',
// 接口地址
url: '/front/user/getInfo'
})
}
// 分页查询用户信息
export const getUserPages = data => {
return request({
method: 'post',
url: '/boss/user/getUserPages',
data
})
}
// 获取所有用户可以分配的角色
export const getAllRole = () => {
return request({
method: 'get',
url: '/boss/role/all'
})
}
// 给用户分配角色
export const allocateUserRoles = data => {
return request({
method: 'post',
url: '/boss/role/allocateUserRoles',
data
})
}
// 查询用户角色
export const getUserRole = userId => {
return request({
method: 'get',
url: `/boss/role/user/${userId}`
})
}
src/views/user/son/card.vue - 使用查询用户角色接口查询用户角色,然后把角色传递给选择器实现默认勾选
<template>
<!-- 容器 -->
<el-card class="box-card">
<!-- 卡片头部 -->
<div slot="header" class="clearfix">
<!-- form表单 -->
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="手机号">
<el-input v-model="formInline.phone" placeholder="手机号"></el-input>
</el-form-item>
<!-- 日期选择器 -->
<el-form-item>
<el-date-picker
v-model="time"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"/>
</el-form-item>
<!-- 查询重置按钮,添加点击事件 -->
<el-form-item>
<el-button type="primary" @click="queryUser">查询</el-button>
<el-button @click="resetUser">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 表格 - 用户展示 -->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="id"
label="用户ID"/>
<el-table-column
label="头像">
<template slot-scope="scope">
<!-- 头像使用数据并设置默认值 -->
<el-avatar size="medium" :src="scope.row.portrait || 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'"></el-avatar>
</template>
</el-table-column>
<el-table-column
prop="name"
label="用户名"/>
<el-table-column
prop="phone"
label="手机号"/>
<el-table-column
label="注册时间">
<template slot-scope="scope">
<!-- 注册时间使用过滤器过滤格式 -->
<span>{{scope.row.createTime | time}}</span>
</template>
</el-table-column>
<el-table-column
label="状态">
</el-table-column>
<el-table-column
label="分配角色">
<template slot-scope="scope">
<!-- 分配角色按钮 -->
<el-button type="text" @click="assignroles(scope.row.id)">分配角色</el-button>
</template>
</el-table-column>
</el-table>
<!-- 对话框 -->
<el-dialog
title="分配角色"
:visible.sync="dialogVisible"
width="50%">
<!-- 选择器,绑定数据,multiple开启多选 -->
<el-select v-model="roltList" multiple placeholder="选择要分配的角色">
<el-option
v-for="item in options"
:key="item.value"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<!-- 取消和确定按钮 -->
<span slot="footer" class="dialog-footer">
<!-- 取消按钮事件函数直接写在行内 -->
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="PerformAssignmentRoles">确 定</el-button>
</span>
</el-dialog>
</el-card>
</template>
<script>
// 引入 - 分页查询用户信息、获取用户全部可分配角色、给用户分配角色、查询用户角色
import { getUserPages, getAllRole, allocateUserRoles, getUserRole } from '@/services/user'
export default {
// 组件命名
name: 'userCard',
data () {
return {
// 接口查询用户信息数据
formInline: {
phone: null
},
// 日期选择器数据
time: '',
// 用户列表数据
tableData: [],
// 信号值 - 控制对话框显示隐藏
dialogVisible: false,
// 选择器选项数据
options: [],
// 选择器选择结果
roltList: [],
// 信号值 - 标记当前用户id
userId: ''
}
},
// 钩子函数
created () {
// 初始化获取用户数据
this.getUser(this.formInline)
},
methods: {
// 分配角色确定按钮点击事件
async PerformAssignmentRoles () {
// 调用接口为用户设置角色
const { data } = await allocateUserRoles({
userId: this.userId,
roleIdList: this.roltList
})
if (data.code === '000000') {
// 如果设置成功,弹出提示,并关闭对话框
this.$message({
message: '保存成功',
type: 'success'
})
this.dialogVisible = false
}
},
// 分配角色按钮事件函数
async assignroles (id) {
// 修改当前用户id
this.userId = id
// 显示对话框
this.dialogVisible = true
// 获取全部可分配角色列表
const { data } = await getAllRole()
if (data.code === '000000') {
// 将所有角色交给选择器
this.options = data.data
}
// 获取当前用户角色
const { data: data2 } = await getUserRole(id)
if (data2.code === '000000') {
// 如果获取成功,遍历全部角色,将角色id传给下拉菜单
data2.data.forEach(item => {
this.roltList.push(item.id)
})
}
},
// 重置按钮事件函数
resetUser () {
// 重置数据
this.time = []
this.formInline.phone = null
},
// 查询按钮事件函数
queryUser () {
// 根据是否选择日期传递不同的参数
if (this.time && this.time.length === 2) {
this.getUser({
phone: this.formInline.phone,
startCreateTime: this.time[0],
endCreateTime: this.time[1]
})
} else {
this.getUser(this.formInline)
}
},
// 获取用户数据
async getUser (obj) {
// 获取数据
const { data } = await getUserPages(obj)
if (data.code === '000000') {
// 如果获取成功,将数据交给列表
this.tableData = data.data.records
}
}
},
// 过滤器
filters: {
// 时间过滤器,用于过滤表格中的用户注册时间
time (data) {
// 直接截取前10位字符串
return data.slice(0, 10)
}
},
watch: {
dialogVisible (newvalue) {
if (!newvalue) {
this.roltList = []
}
}
}
}
</script>