先看下具体实现效果
在首页渲染侧导航时:使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转 main种预留了 router-view 组件 路由配置中 所有二级侧边导航都是 home的 children所以可以直接跳转到 后续的二级侧导航也是如此
面包屑部分
很简单直接引用组件即可
<!-- 面包屑导航-->
<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-card> 组件当中
搜索部分
采用layout 布局 24分栏 gutter 属性来指定每一栏之间的间隔,默认间隔为 0。
通过 row 和 col 组件,并通过 col 组件的 span
属性(占24格当中的几格)我们就可以自由地组合布局。
v-model="prams.query" 方便储存数据 发起检索
clearable 属性 有一键清空输入框的小叉号
@clear="getUserList" 点击clearable触发的事件回调
在el-input 使用 插槽slot 决定此元素出现在输入框的哪个位置 prepend前面 append后面
点击输入框里面的叉号 或者 输入框 后面的搜索按钮 都会触发 getUserList
区别就是 @clear 触发的 清空了 query参数
async getUserList(){
const {data:res} = await this.$http.get('users',{params:this.prams})
if (res.meta.status !== 200) return this.$Msg.error('获取用户列表失败')
this.userList = res.data.users
this.total = res.data.total
}
<el-row :gutter="20">
<el-col :span="8">
<el-input placeholder="请搜索内容"
v-model="prams.query"
clearable
@clear="getUserList">
<el-button slot="append"
icon="el-icon-search"
@click="getUserList"></el-button>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="addUsers">添加用户</el-button>
</el-col>
</el-row>
渲染用户列表的表格
:data 需要渲染的数据是 上面函数返回赋值的 userList
srtipe 表格隔行变色(斑马纹) border 描边
当el-table
元素中注入data
对象数组后,在el-table-column
中用prop
属性来对应对象中的键名即可填入数据,用label
属性来定义表格的列名。可以使用width
属性来定义列宽。
通过给 type=index
的列传入 index
属性,可以自定义索引。该属性传入数字时,将作为索引的起始值。也可以传入一个方法,它提供当前行的行号(从 0
开始)作为参数,返回值将作为索引展示。
<el-table
:data="userList"
style="width: 100%"
stripe
border>
<el-table-column type="index" label="#"></el-table-column>
<el-table-column
prop="username"
label="用户名"
width="180">
</el-table-column>
<el-table-column
prop="email"
label="邮箱">
</el-table-column>
<el-table-column
prop="mobile"
label="电话">
</el-table-column>
<el-table-column
prop="role_name"
label="角色">
</el-table-column>
<el-table-column
label="状态"
width="180">
<template slot-scope="scope">
<!-- <template slot-scope="scope"> 作用域插槽 scope.row获得当前的数据-->
<el-switch v-model="scope.row.mg_state" @change="pubUserState(scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column
label="操作">
<template slot-scope="scope">
<!-- 修改按钮-->
<el-tooltip effect="dark" content="修改此用户资料" placement="top" :enterable="false">
<el-button type="primary" icon="el-icon-edit" size="small" @click="editBox(scope.row.id)"></el-button>
</el-tooltip>
<!-- 删除按钮-->
<el-tooltip effect="dark" content="删除此用户" placement="top" :enterable="false">
<el-button type="danger" icon="el-icon-delete" size="small" @click="open(scope.row.id)"></el-button>
</el-tooltip>
<!-- 分配角色按钮-->
<el-tooltip effect="dark" content="分配此用户权限" placement="top" :enterable="false">
<el-button type="warning" icon="el-icon-s-help" size="small" @click="open3(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
修改用户的状态:
Switch 开关组件
绑定v-model
到一个Boolean
类型的变量。可以使用active-color
属性与inactive-color
属性来设置开关的背景色
状态发生改变时 触发回调(通过作用域插槽 获得路径拼接的 用户ID 和当前状态)如果更新失败再返回原来的状态
async pubUserState(userData){
const {data:res} = await this.$http.put(`users/${userData.id}/state/${userData.mg_state}`)
if (res.meta.status !== 200){
userData.mg_state = !userData.mg_state
return this.$Msg.error('更新用户状态失败')
}
this.$Msg.success('更新用户状态成功')
}
修改用户的资料
按钮的外侧使用 el-tooltip 包裹 鼠标移入会显示提示文字
点击按钮弹出编辑框 同时根据传入的用户id 请求好之前的数据 渲染进去
//点击按钮 显示编辑信息对话框 并且根据ID 获取用户信息 渲染到对应列表
async editBox(id){
const {data : res} = await this.$http.get(`users/${id}`)
if (res.meta.status !== 200) return this.$Msg.error('查询此用户信息失败!')
this.editUsersInfo = res.data
this.editUsersBox = true
}
之前预留的数据空间:
editUsersBox:false,
editUsersInfo:{}
晾在一旁的询问框组件:
是否显示由 editUsersBox 布尔值决定
@close 关闭的时候清空 表单数据(根据form的ref查找)
// 编辑用户对话框关闭后 重置表单
EUIClose(){
this.$refs.editUserFormRef.resetFields()
},
点击确定按钮 提交更新数据 提交数据之前先进行规则验证 通过验证后 发送修改请求
ToEditUsers(){
this.$refs.editUserFormRef.validate(async valid =>{
if (!valid) return
const {data : res} = await this.$http.put(`users/${this.editUsersInfo.id}`,{
email:this.editUsersInfo.email,
mobile:this.editUsersInfo.mobile
})
if (res.meta.status !== 200) return this.$Msg.error('修改用户信息失败!')
this.$Msg.success('修改用户信息成功!')
await this.getUserList()
this.editUsersBox = false
})
},
<el-dialog
title="修改用户资料"
:visible.sync="editUsersBox"
@close="EUIClose"
width="50%">
<el-form ref="editUserFormRef"
:model="editUsersInfo"
class="demo-ruleForm"
:rules="FormDataRules"
label-width="100px">
<el-form-item label="用户名">
<el-input v-model="editUsersInfo.username" disabled></el-input>
</el-form-item>
<el-form-item label="用户邮箱" prop="email">
<el-input v-model="editUsersInfo.email"></el-input>
</el-form-item>
<el-form-item label="用户手机号" prop="mobile">
<el-input v-model="editUsersInfo.mobile"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="ToEditUsers">确 定</el-button>
<el-button @click="editUsersBox = false">取 消</el-button>
</span>
</el-dialog>
简单的表单验证 如必填项 限制最大最小字符长度 很简单 在登录的时候已经验证过
在 el 表单使用正则表达式验证表单:写在组件的data里:
data(){
let checkEmail = (rule,value,cb) =>{
const regEmail = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
// 验证正确就是合法的邮箱 就 瑞腾 出去
if (regEmail.test(value)){
return cb()
}
// 否则就返回错误信息
cb(new Error('请输入正确的邮箱'))
}
let checkMobile = (rule,value,cb) =>{
const regMobile = /^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$/
// 验证正确就是合法的手机号 就 瑞腾 出去
if (regMobile.test(value)){
return cb()
}
// 否则就返回错误信息
cb(new Error('请输入正确的手机号'))
}
let validatePass2 = (rule, value, callback) => {
if(value === this.addUsersInfo.password){
return callback()
}
callback(new Error('密码不一致'))
}
return{
// 通用 表单验证
FormDataRules:{
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
],
password: [
{ min: 6, max: 16, message: '长度在 6 到 16 个字符', trigger: 'blur' },
{ required: true, message: '请输入登录密码', trigger: 'blur' }
],
passwordS: [
{ required: true, message: '请输入确认密码', trigger: 'blur' },
{ validator:validatePass2, trigger: 'blur' }
],
email: [
{ required: true, message: '请输入用户邮箱', trigger: 'blur' },
{ validator:checkEmail, trigger: 'blur' }
],
mobile: [
{ required: true, message: '请输入用户手机号', trigger: 'blur' },
{ validator:checkMobile, trigger: 'blur' }
]
},
},
// 编辑用户对话框关闭后 重置表单
EUIClose(){
this.$refs.editUserFormRef.resetFields()
}
删除用户
操作下面按钮包裹结构一致
点击的回调 主要是有调用$confirm
方法 确定消息
这里是注册的时候用别名
Vue.prototype.$queding = MessageBox.confirm
Vue.prototype.$Msg = Message
使用 async await 简化promise 代码 https://blog.csdn.net/benlalagang/article/details/126246961
async open(id){
//弹窗询问用户是否删除数据
const confirmResult = await this.$queding(
'此操作将永久删除该用户, 是否继续?',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).catch(err => err)
// 如果用户确认删除,则返回值为字符串 confirm
// 如果用户取消删除,则返回值为字符串 cancel
// console.log(confirmResult)
if (confirmResult !== 'confirm'){
return this.$Msg.info('已取消删除')
}
const {data:res} = await this.$http.delete(`users/${id}`)
if (res.meta.status !== 200) return this.$Msg.error('删除用户失败!')
this.$Msg.success('删除用户成功!')
await this.getUserList()
},
添加用户
流程和编辑用户一样
1.点击添加用户按钮 显示对话框(切换 :visible.sync 的布尔值)
2.使用组件布局好 对话框内容 用户填写相关信息 通过验证后 发送给服务器
3.服务器成功处理之后 更新用户数据列表
// 点击添加用户按钮 显示对话框
addUsers(){
this.addUsersBox = true
},
// 对话框关闭后 重置内部表单
AUIClose(){
this.$refs.addUserFormRef.resetFields()
},
// 发起请求添加用户数据
ToAddUsers(){
// 先预校验
this.$refs.addUserFormRef.validate(async valid =>{
if (!valid) return
const {data : res} = await this.$http.post('users',this.addUsersInfo)
if (res.meta.status !== 201) return this.$Msg.error('添加用户失败!')
this.$Msg.success('添加用户成功!')
await this.getUserList()
this.addUsersBox = false
})
},
分配用户角色权限
点击显示对话框 对应渲染 相应数据、用户可选角色列表,渲染成el-select 选择器、选择好后发送给服务器处理
<!-- 点击修改用户 角色 的对话框-->
<el-dialog
title="分配用户角色"
:visible.sync="NPCUsersBox"
@close="NPCClose"
width="35%">
<div style="margin-bottom: 12px">当前的用户:{{NPCUsersInfo.username}}</div>
<div style="margin-bottom: 12px">当前的角色:{{NPCUsersInfo.role_name}}</div>
<div>
<el-select v-model="currRID" placeholder="请分配角色">
<el-option v-for="lise in roleList"
:label="lise.roleName"
:key="lise.id"
:value="lise.id"></el-option>
</el-select>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="ToNPCUsers">确 定</el-button>
<el-button @click="NPCUsersBox = false">取 消</el-button>
</span>
</el-dialog>
<script>
// 分配用户权限相关操作
// 点击表单内的分配权限按钮 操作
async open3(UsersInfo){
this.NPCUsersInfo = UsersInfo
const {data : res} = await this.$http.get('roles')
if (res.meta.status !==200) return this.$Msg.error('获取角色列表失败')
this.roleList = res.data
this.NPCUsersBox = true
},
// 点击 添加角色对话框内的相关操作
async ToNPCUsers(){
if (!this.currRID) return this.$Msg.error('请选择要分配的角色!')
const {data:res} = await this.$http.put(`users/${this.NPCUsersInfo.id}/role`,{rid:this.currRID})
if (res.meta.status !==200) return this.$Msg.error('分配角色失败!')
this.NPCUsersBox = false
this.$Msg.success('分配角色成功!')
await this.getUserList()
},
// 分配角色对话框关闭时 事件
NPCClose(){
this.NPCUsersInfo = {}
this.currRID=''
},
</script>
页码的切换
Pagination 分页
<!-- 页码部分-->
<el-pagination
每页显示多少条发生改变的回调函数
@size-change="handleSizeChange"
选择第哪一页发生变化的回调函数
@current-change="handleCurrentChange"
默认显示的哪一页
:current-page="prams.pagenum"
可选项切换每页显示几条
:page-sizes="[2, 4, 8, 16]"
默认每页显示几条
:page-size="prams.pagesize"
要显示哪些东西 依次是 总数、每页显示数量(可切换)、上一个、当前页码、下一个、要跳转到哪一页
layout="total, sizes, prev, pager, next, jumper"
总数
:total="total">
</el-pagination>
prams:{
query:'',
// 当前页数
pagenum:1,
// 当前每页显示多少条数据
pagesize:8
}
handleSizeChange(newSize){
this.prams.pagesize = newSize
this.getUserList()
},
handleCurrentChange(newPage){
this.prams.pagenum = newPage
this.getUserList()
},
prams 是获取用户列表携带的参数、当改变每页选择的数据尺寸或者 数据选中页码时用最新携带的参数重新发起请求
用户列表页面就完成了 以后的页面相似的功能可以返回这里看