用户列表开发
表格中Boolean值渲染成开关按钮
作用域插槽
(即带数据的插槽)让父组件在填充子组件的插槽内容时使用子组件的数据
slot-scope=“作用域名”(作用域名.数据名来使用子组件的数据)
通过 Scoped slot
可以获取到 row, column, $index 和 store(table 内部的状态管理)的数据
什么时候会用到作用域插槽?
需要在列表中进行非文本渲染,比如渲染图片、按钮、进度条等
首先,在表格列el-table-column中放一个模板template
使用slot-scope=“scope”,scope接收数据,使用scope.row属性获取当前行数据。将其打印是输出一下:
<template slot-scope="scope">{{scope.row}}</template>
然后,从打印结果可以看到scope.row中有一个mg_state:false,所以我们可以通过scope.row.mg_state获取到该数据,并且将此数据渲染成开关样式,使用el-switch,绑定v-model
到一个Boolean
类型的变量,完整代码如下:
<el-table-column label="状态"> <template slot-scope="scope"> <el-switch v-model="scope.row.mg_state"></el-switch> </template> </el-table-column>
效果如下:
插槽形式自定义列的渲染
<el-table-column label="操作" width="180px"> //让按钮在一行显示,给当前列加宽 <template> <!-- 修改按钮 --> <el-button type="danger"//红色 icon="el-icon-edit" size="mini"></el-button> <!-- 删除按钮 --> <el-button type="primary"//蓝色 icon="el-icon-delete" size="mini"></el-button> <!-- 分配角色按钮 --> //el-tooltip鼠标移动到该按钮显示提示信息 <el-tooltip effect="dark"//黑色提示框 content="分配角色"//提示信息 placement="top"//上面显示 :enterable="false"> //鼠标离开,隐藏tooltip //enterable鼠标是否可进入到 tooltip 中,Boolean —默认true <el-button type="warning"//橙色 icon="el-icon-setting" size="mini"></el-button> </el-tooltip> </template> </el-table-column>
实现数据分页效果
<el-pagination //切换分页条(每页显示多少条)时触发 @size-change="handleSizeChange" //切换页码时触发 @current-change="handleCurrentChange" :current-page="queryInfo.pagenum"//当前页码 :page-sizes="[1, 2, 5, 10]"//分页条 :page-size="queryInfo.pagesize"//当前每页显示多少条数据 //layout表示会在页面上展示哪些功能组件 layout="total, sizes, prev, pager, next, jumper" :total="total"> //total表示一共多少数据(动态绑定data里面的total) </el-pagination>
data () { return { // 获取用户列表的参数对象 queryInfo: { query: '', // 当前的页数 pagenum: 1, // 当前每页显示多少条数据 pagesize: 2 }, userlist: [], total: 0 } },
methods:{ // 监听pagesize改变的事件 handleSizeChange (newSize) { // console.log(newSize) // 将最新的每页显示多少条数据保存到data里面的pageSize this.queryInfo.pagesize = newSize // 更新表格数据(重新发起get请求获取最新的数据) this.getUserList() }, // 监听页码值改变的事件 handleCurrentChange (newPage) { // console.log(newPage) this.queryInfo.pagenum = newPage this.getUserList() }
实现用户状态的修改
在视图界面修改状态信息,实现后台保存修改
①
首先,要监听到switch开关状态信息的改变
监听switch开关状态信息
事件名称 | 说明 | 回调参数 |
---|---|---|
change | switch 状态发生变化时的回调函数 | 新状态的值 |
给switch添加一个点击事件:
<el-switch v-model="scope.row.mg_state" @change="userStateChanged(scope.row)"></el-switch>
// 监听switch开关状态的改变 userStateChanged (userinfo) { console.log(userinfo) }
后台打印监听结果:
开关关上时:
开关打开时:
监听数据成功
②
然后,调用对应的api接口将监听的结果保存到数据库
调用api接口保存数据
这里发起api请求时,uId是动态参数,为了插入动态数据,需要用到模板字符串:
es6 模板字符串
参考:ES6之反引号(`)标识的作用——字符串插入变量${插值变量名} & 多行字符串 & 标签模板-tag函数_viceen的博客-CSDN博客_es6反引号
ES6 模板字符串(Template String)是增强版的字符串,用反引号(`)标识,而不是单引号(’)或双引号(“)引号;它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
字符串插入变量和表达式。变量名写在 ${} 中
let info = `我是${name},我${age + 1}岁了。` //等价于: let info="我是"+name+",我"+(age+1)+"岁了。"
请注意,插值(${
插值}
)内的任何占位符都将被视为JavaScript表达式并进行评估,例如,您可以进行数学运算。
console.log(`1和1的插值运算${1 + 1}`);
查阅api文档:
1.3.3. 修改用户状态
-
请求路径:users/:uId/state/:type
-
请求方法:put //一般发生修改都是调用put请求
-
请求参数
参数名 | 参数说明 | 备注 |
---|---|---|
uId | 用户 ID | 不能为空携带在url中 |
type | 用户状态 | 不能为空携带在url中 ,值为 true 或者 false |
-
响应数据
{ "data": { "id": 566, "rid": 30, "username": "admin", "mobile": "123456", "email": "bb@itcast.com", "mg_state": 0 }, "meta": { "msg": "设置状态成功", "status": 200 } }
发起请求:
发起put请求后会返回promise对象,所以加上await 和asyns简化promise为一个data属性,并且将data重命名为res。判断是否设置状态成功,若失败没有返回200(即视图数据已经更改,数据库数据更新失败)需要把视图状态重置回原来状态(即状态取反);反之,返回200数据,更新状态成功,输出提示信息。
完整switch点击事件如下:
// 监听switch开关状态的改变 async userStateChanged (userinfo) { console.log(userinfo) const { data: res } = await this.$http.put(`users/${userinfo.id}/state/${userinfo.mg_state}`) if (res.meta.status !== 200) { userinfo.mg_state = !userinfo.mg_state return this.$message.error('更新用户状态失败!') } return this.$message.success('更新用户状态成功!') }
页面效果如下,点击状态按钮,上方弹出message对话框
并且更改完状态信息,再次刷新页面,状态信息不会变,说明修改的状态信息已经成功保存到数据库
实现搜索功能
当用户在文本框输入信息后,点击搜索按钮,可以根据指定名称搜索不同的用户。应该将文本框和data中的数据进行双向绑定;绑定完成后,在点击搜索按钮时,调用获取列表的函数进行查询。
首先,给input输入框在data中定义一个关键字query
data(){return{queryInfo: { // 搜索输入框关键字 query: '', // 当前的页数 pagenum: 1, // 当前每页显示多少条数据 pagesize: 2 },
v-model双向绑定,button添加点击事件(绑定获取用户列表事件进行查询):
<!-- 搜索与添加区域 --> <el-input placeholder="请输入内容" v-model="queryInfo.query"> <el-button slot="append" icon="el-icon-search" @click="getUserList"></el-button> </el-input>
效果演示(查询到adm所有数据):
实现可清空input
此时,我们查询完成数据后,把输入框内容清空,点击查询按钮可以查询到所有用户信息。现在我们可以在输入框添加一个可以把输入框数据都清空的按钮,点击按钮输入框内容清空同时查询出所有用户信息。
查阅element文档input中有一个可清空输入框,是使用clearable
属性得到的
<!-- 搜索与添加区域 --> <el-input placeholder="请输入内容" v-model="queryInfo.query" clearable>
加上此属性后,点击清空按钮输入框内容确实被清空了,但是表格数据并没有被重置为所有用户信息。查阅文档,input下方有一个clear事件
clear | 在点击由 clearable 属性生成的清空按钮时触发 |
---|---|
<el-input placeholder="请输入内容" v-model="queryInfo.query" clearable @clear="getUserList">
点击清空按钮成功获取到所有用户信息。
实现添加用户的功能
点击添加用户按钮弹出dialog对话框,点击取消确定按钮或者对话框外的其他任意区域都能实现对话框隐藏
dialog对话框
element官网复制以下内容至el-card的最下面
<!-- 添加用户的对话框 --> <el-dialog title="提示" //属性绑定boolean,控制对话框的显示与隐藏 :visible.sync="addDialogVisible" width="50%"> <!-- 内容主体区域 --> <span>这是一段信息</span> <!-- 底部区域 --> //footer-Dialog 按钮操作区的内容,使用插槽插入 <span slot="footer" class="dialog-footer"> <el-button @click="addDialogVisible = false">取 消 </el-button> <el-button type="primary" @click="addDialogVisible = false">确 定 </el-button>//置为false,点击确定或取消按钮隐藏对话框 </span> </el-dialog>
data(){return{ // 控制添加用户对话框的显示与隐藏 addDialogVisible: false//默认模式不显示对话框
给添加用户写一个点击事件绑定对话框
<el-button type="primary" @click="addDialogVisible=true">添加用户</el-button>
设为true表示点击添加用户按钮时显示对话框
对话框中渲染一个表单
dialog内容主体区域替换为form表单:
<!-- 内容主体区域 --> //form表单使用model数据双向绑定addForm数组,rules绑定验证规则对象, ref引用对象,label-width指定文本长度 <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="70px"> //prop指定具体校验规则,此规则在addFormRules中具体定义 <el-form-item label="用户名" prop="username"> //输入框使用v-model进行数据双向绑定 <el-input v-model="addForm.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input v-model="addForm.password"></el-input> </el-form-item> <el-form-item label="邮箱" prop="email"> <el-input v-model="addForm.email"></el-input> </el-form-item> <el-form-item label="手机" prop="mobile"> <el-input v-model="addForm.mobile"></el-input> </el-form-item> </el-form>
data () { return { // 添加用户的表单数据 addForm: { username: '', password: '', email: '', mobile: '' }, // 添加表单的验证规则对象 addFormRules: { username: [ // required: true表示必填, message: '请输入用户名'则为提示信息,trigger: 'blur'光标移开时触发校验,min,max则校验了我们要求的字符串长度 { required: true, message: '请输入用户名', trigger: 'blur' }, { min: 3, max: 10, message: '用户名的长度在3~10个字符之间', trigger: 'blur' } ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, { min: 6, max: 15, message: '密码的长度在6~15个字符之间', trigger: 'blur' } ], email: [ { required: true, message: '请输入邮箱', trigger: 'blur' } ], mobile: [ { required: true, message: '请输入手机', trigger: 'blur' } ] } } },
效果演示:
自定义校验规则
使用自定义校验规则校验邮箱和手机号,首先在data中非return{}的部分定义校验规则,然后在rules中进行绑定。
如下:箭头函数,接收3个参数,rule,value和cb,其中value
是要验证的字段的值,cb
是验证以后的回调函数 如果值可以通过正则校验,就return cb()
否则调用cb返回错误信息
data () { // 验证邮箱的规则 const checkEmail = (rule, value, cb) => { // 验证邮箱的正则表达式 const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/ if (regEmail.test(value)) { // 合法的邮箱 return cb() } cb(new Error('请输入合法的邮箱')) } // 验证手机号的规则 const checkMobile = (rule, value, cb) => { const regMobile = /^(0|86|17951)?(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57])[0-9]{8}$/ if (regMobile.test(value)) { return cb() } cb(new Error('请输入合法的手机号')) } return { 。。。 // 添加表单的验证规则对象 addFormRules: { 。。。 //validator绑定自定义校验规则 email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }, { validator: checkEmail, trigger: 'blur' }], mobile: [{ required: true, message: '请输入手机', trigger: 'blur' }, { validator: checkMobile, trigger: 'blur' }] }
添加用户表单重置
关闭对话框后,重置表单。使再次打开对话框,里面没有之前数据,是一个新的表单。首先,监听对话框的关闭事件。然后,在关闭事件中重置表单。
elementui文档dialog有一个close事件:
只有这个事件触发了,就说明这个对话框被关闭了。对话框被关闭,我们就重置表单数据。
通过ref引用调用resetFields方法,重置表单。
<!-- 添加用户的对话框 --> <el-dialog title="添加用户" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed">
// 监听添加用户对话框的关闭事件 addDialogClosed () { this.$refs.addFormRef.resetFields() }
this.$refs[name].resetFields();的使用:
重置表单方法的注意事项:
-
Form
必须要有ref
属性 -
Form
必须绑定:model
-
Form
的FormItem
中必须要有prop
属性 -
Form
包裹的元素绑定值需与FormItem
中prop
属性名称保持一致
添加用户的预验证功能
填写完添加用户的信息,点击确定的时候调用一下函数对整个表单进行一下预验证。
<el-button type="primary" @click="addUser">确 定</el-button>
// 点击按钮,添加新用户(预验证) addUser () { this.$refs.addFormRef.validate(valid => { console.log(valid) }) }
未填写任何信息,点击确定,校验失败:
输入完整信息,点击确定,打印true
// 点击按钮,添加新用户(预验证) addUser () { this.$refs.addFormRef.validate(valid => { // 如果验证失败直接return if (!valid) return // 验证通过,可以发起添加用户的网络请求 }) }
发起请求添加一个新用户
发什么请求呢->查阅文档:
1.3.2. 添加用户
-
请求路径:users
-
请求方法:post
-
请求参数
参数名 | 参数说明 | 备注 |
---|---|---|
username | 用户名称 | 不能为空 |
password | 用户密码 | 不能为空 |
邮箱 | 可以为空 | |
mobile | 手机号 | 可以为空 |
-
响应数据
"meta": { "msg": "用户创建成功", "status": 201 }
请求参数是添加用户的表单数据存在data()return{中的addForm函数中,所以直接传参addForm即可。
post返回promise函数,使用async和await
// 点击按钮,添加新用户(预验证) addUser () { this.$refs.addFormRef.validate(async valid => { // 如果验证失败直接return if (!valid) return // 验证通过,可以发起添加用户的网络请求 const { data: res } = await this.$http.post('users', this.addForm) if (res.meta.status !== 201) { this.$message.error('添加用户失败!') } this.$message.success('添加用户成功!') //隐藏对话框 this.addDialogVisible = false // 重新获取用户列表数据 this.getUserList() }) }
实现用户信息修改操作
dialog对话框
点击表格操作栏蓝色修改按钮,会弹出修改用户信息的对话框
<!-- 修改按钮 --> <el-button type="danger" icon="el-icon-edit" size="mini" @click="showEditDialog()"></el-button>
<!-- 修改用户对话框 --> <el-dialog title="修改用户" :visible.sync="editDialogVisible" width="50%"> <span>这是一段信息</span> <span slot="footer" class="dialog-footer"> <el-button @click="editDialogVisible = false">取 消 </el-button> <el-button type="primary" @click="editDialogVisible = false">确 定 </el-button> </span> </el-dialog>
data(){ return{ // 控制修改用户对话框的显示与隐藏 editDialogVisible: false } }
// 展示编辑用户的对话框 showEditDialog () { this.editDialogVisible = true }
点击按钮显示对话框:
根据ID查询用户信息
弹出对话框中肯定要拿到以前旧数据,才能对数据进行修改。所以我们现在根据ID查询一下用户信息。
<template slot-scope="scope"> <!-- 修改按钮 --> <el-button type="danger" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.id)"></el- button>//传参,把这一行的id传过来
// 展示编辑用户的对话框 async showEditDialog (id) { console.log(id)//点击按钮,打印这一行数据的id this.editDialogVisible = true }
测试一下,打印id成功
查阅文档:
1.3.4根据 ID 查询用户信息
-
请求路径:userss/:id
-
请求方法:get
-
请求参数
参数名 | 参数说明 | 备注 |
---|---|---|
id | 角色 ID | 不能为空携带在url中 |
-
响应参数
参数名 | 参数说明 | 备注 |
---|---|---|
id | 用户 ID | |
role_id | 角色 ID | |
mobile | 手机号 | |
邮箱 |
-
响应数据
{ "data": { "id": 503, "username": "admin3", "role_id": 0, "mobile": "00000", "email": "new@new.com" }, "meta": { "msg": "查询成功", "status": 200 } }
编辑按钮点击事件:
// 展示编辑用户的对话框 async showEditDialog (id) { // console.log(id) this.editDialogVisible = true const { data: res } = await this.$http.get('roles/:id', id) if (res.meta.status !== 200) { this.$message.error('查询用户信息失败!') } // 获取成功就把数据保存到editForm中 this.editForm = res.data //这里传的是整个数组,所以data里面editForm数组里面不用定 义具体数据 }
data(){return{ // 查询到的用户信息数据 editForm: {}
绘制修改用户的表单
<!-- 修改用户对话框 --> <el-dialog title="修改用户" :visible.sync="editDialogVisible" width="50%"> <!-- 内容主体区域 --> <el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="70px"> <el-form-item label="用户名"> <el-input v-model="editForm.username" disabled>//用户名disable设为不能修改 </el-input> </el-form-item> <el-form-item label="邮箱" prop="email"> <el-input v-model="editForm.email"></el- input> </el-form-item> <el-form-item label="手机" prop="mobile"> <el-input v-model="editForm.mobile"></el- input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="editDialogVisible = false">取 消</el-button> <el-button type="primary" @click="editDialogVisible = false">确 定</el-button> </span> </el-dialog>
data(){ // 验证邮箱的规则 const checkEmail = (rule, value, cb) => { // 验证邮箱的正则表达式 const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/ if (regEmail.test(value)) { // 合法的邮箱 return cb() } cb(new Error('请输入合法的邮箱')) } // 验证手机号的规则 const checkMobile = (rule, value, cb) => { const regMobile = /^(0|86|17951)?(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57])[0-9]{8}$/ if (regMobile.test(value)) { return cb() } cb(new Error('请输入合法的手机号')) } return{ // 查询到的用户信息对象 editForm: { }, // 修改表单的验证规则对象 editFormRules:{ email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }, { validator: checkEmail, trigger: 'blur' }], mobile: [{ required: true, message: '请输入手机', trigger: 'blur' }, { validator: checkMobile, trigger: 'blur' }] }
实现修改表单的关闭之后的重置操作
关闭对话框,重置表单(之前的验证规则提示信息被重置)。需要监听对话框关闭之后的close事件
<!-- 修改用户对话框 --> <el-dialog title="修改用户" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed">
// 监听修改用户对话框的关闭事件 editDialogClosed () { this.$refs.editFormRef.resetFields() }
提交修改之前的表单预验证操作
点击确定按钮之后对表单信息进行预验证,只有验证通过才能提交表单信息。
<el-button type="primary" @click="editUserInfo">确 定</el-button>
// 修改用户信息并提交 editUserInfo () { this.$refs.editFormRef.validate(valid => { console.log(valid) if (!valid) return // 发起修改用户信息的数据请求 }) }//验证通过valid为true,验证不通过valid为false
提交修改用户信息
查阅文档:
1.3.5. 编辑用户提交
-
请求路径:users/:id
-
请求方法:put
-
请求参数
参数名 | 参数说明 | 备注 |
---|---|---|
id | 用户 id | 不能为空 参数是url参数:id |
邮箱 | 可以为空 | |
mobile | 手机号 | 可以为空 |
// 修改用户信息并提交 editUserInfo () { //预验证 this.$refs.editFormRef.validate(async valid => { console.log(valid) if (!valid) return // 发起修改用户信息的数据请求 const { data: res } = await this.$http.put('users/' + this.editForm.id, { email: this.editForm.email, mobile: this.editForm.mobile }) if (res.meta.status !== 200) { return (this.$message.error('更新用户信息失败!')) } // 关闭对话框 this.editDialogVisible = false // 刷新数据列表 this.getUserList() // 提示修改成功 this.$message.success('更新用户信息成功!') }) }
实现删除用户的操作
点击删除按钮,弹出是否确认删除的弹框,点击确定删除用户信息,点击取消不删除用户信息。
使用elementUI弹框组件MessageBox
先给删除按钮添加一个点击事件并获取当前行的id,
<!-- 删除按钮 --> <el-button type="primary" icon="el-icon-delete" size="mini" @click="removeUserById(scope.row.id)"></el- button>
// 根据id删除对应的用户信息 async removeUserById (id) { // 弹框询问用户是否删除数据 const confirmResult = await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) // 如果用户确认删除,则返回为字符串 confirm console.log(confirmResult) }
$confirm函数返回的是promise,所以加了一个await和async简化promise,并且使用confirmResult接收,然后点击弹框的确定按钮,返回字符串 confirm,点击取消按钮,报错(因为点击取消会触发$confirm里面的一个错误),所以我们这里使用catch捕获这个错误消息(.catch(err=>{return err)可以简写成(err => err))并且把错误消息return给confirmResult接收。此时再点击弹窗中的取消按钮就不会报错了,而是打印了字符串cancel。然后,我们就可以根据confirmResult的值是confirm还是cancel判断用户点击了确认还是取消。
// 根据id删除对应的用户信息 async removeUserById (id) { // 弹框询问用户是否删除数据 const confirmResult = await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).catch(err => err) // 如果用户确认删除,则返回为字符串 confirm // 如果用户取消删除,则返回为字符串 cancel // console.log(confirmResult) if (confirmResult !== 'confirm') { return this.$message.info('已取消删除') } console.log('确认了删除') }
完成删除用户操作
查阅文档:
1.3.6. 删除单个用户
-
请求路径:users/:id
-
请求方法:delete
-
请求参数
参数名 | 参数说明 | 备注 |
---|---|---|
id | 用户 id | 不能为空参数是url参数:id |
-
响应参数
-
响应数据
{ "data": null, "meta": { "msg": "删除成功", "status": 200 } }
// 根据id删除对应的用户信息 async removeUserById (id) { // 弹框询问用户是否删除数据 const confirmResult = await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).catch(err => err) // 如果用户确认删除,则返回为字符串 confirm // 如果用户取消删除,则返回为字符串 cancel // console.log(confirmResult) if (confirmResult !== 'confirm') { return this.$message.info('已取消删除') } const { data: res } = await this.$http.delete('users/' + id) if (res.meta.status !== 200) { return this.$message.error('删除用户失败!') } this.$message.success('删除用户成功!') this.getUserList() console.log('确认了删除') }
提交用户列表功能代码
新建一个user分支,将代码提交到user,然后把user分支提交到码云,然后把user里面的内容更新到主分支master,最后git push 把所有代码提交到码云。
git branch//查看当前分支 git check -b user//新建user分支并且切换到user分支 git status//查看一下工作区的状态,有改过的文件就是红色的 git add .//把改过的文件添加到缓存区,红色文件变色绿色 git commit -m "完成用户列表功能的开发" //提交代码 git status// working tree clean git push -u origin user//把user分支提交到码云 git checkout master//切换到主分支 git merge user//把user分支的文件更新到master git push//提交