在这里,我们将基于表单,讲解对元素的增删改查,以及在表单上的一系列操作(预验证、提交、重置)。
这是在管理系统里最常见的操作,涉及有用户管理、商品管理、车辆管理、司机管理等等。
我们将继续基于《电商管理系统》,探讨前端的基本管理操作。
在增删改查的基本管理中,涉及到的组件库的组件的使用,我们将进行探讨
这里我们以用户管理为范例。
目录
1、显示所有用户并分页展示(查)
我们使用element-plus组件库中的Table组件来显示所有数据,并进行绑定(数据发生变化时,表格内容会动态发生变化)
我们需要在生命周期函数created()中获取为Table组件绑定的列表数据。
注:
created()函数是一种生命周期函数
什么是生命周期呢?生命周期是指,一个Vue实例或组件从创建到销毁所经历的一系列过程(期间会调用一系列函数,我们重写生命周期函数,就可以在不同的生命周期点调用不同的方法)
created函数是指:在模板渲染成html前执行的函数
在created函数中调用this.getUserList()方法。
在methods中写入getUserList()方法。
async getUserList() {
const { data: res } = await this.$axios.get('/users', { params: this.queryInfo });
if (res.meta.status !== 200) {
return this.$message.error('获取用户列表失败!');
}
this.userlist = res.data.users;
this.total = res.data.total;
console.log(res);
},
table绑定的是userlist列表(userlist列表初值需要在data()函数的返回值中声明)
以用户列表为例,table的代码:
<!-- 用户列表区域 -->
<el-table :data="userlist"
border
stripe>
<el-table-column type="index"></el-table-column>
<el-table-column label="姓名"
prop="username"></el-table-column>
<el-table-column label="邮箱"
prop="email"></el-table-column>
<el-table-column label="电话"
prop="mobile"></el-table-column>
<el-table-column label="角色"
prop="role_name"></el-table-column>
<el-table-column label="状态">
<!-- 作用域插槽 -->
<template v-slot="scope">
<!-- {{scope.row}} -->
<el-switch v-model="scope.row.mg_state"
@change="userStateChanged(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作"
width="180px">
<template v-slot="scope">
<!-- 修改按钮 -->
<el-button type="primary"
icon="el-icon-edit"
size="mini"
@click="showEditDialog(scope.row.id)"></el-button>
<!-- 删除按钮 -->
<el-button type="danger"
icon="el-icon-delete"
size="mini"
@click="removeUserById(scope.row.id)"></el-button>
<!-- 分配角色按钮 -->
<el-tooltip effect="dark"
content="分配角色"
placement="top"
:enterable="false">
<el-button type="warning"
icon="el-icon-setting"
size="mini"
@click="setRole(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
在el-table-column中用prop属性对应对象中的键名来填入数据,用label属性定义表格的列名。可以使用width属性来定义列宽。
列表中有多少个对象,就会有多少行。
分页组件
在Table下面需要控制分页,使用el-pagination
<!-- 分页区域 --> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryInfo.pagenum" :page-sizes="[1, 2, 5, 10]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination>
属性:
使用current-page属性双向绑定当前页数,page-sizes属性表示每页显示个数选择器的选项设置,page-size属性双向绑定每页显示条目个数,total属性双向绑定总条目数
layout表示组件布局,total此处表示总条目数,sizes可选每页显示可数选择器,prev表示跳转到上一页,pager表示当前页码,next表示调转到下一页,jumper表示直接调转到某一页
配套事件:
size-change表示每页条目数改变时触发,传递的参数是每页条目数
// 监听pagesize改变的事件 handleSizeChange(newSize) { // console.log(newSize); this.queryInfo.pagesize = newSize; this.getUserList(); },
方法中具体写的是改变发起请求时的每页条目数的参数,再重新发起请求
current-change表示改变页码时触发,传递的参数是当前页码
// 监听页码值改变的事件 handleCurrentChange(newPage) { // console.log(newPage); this.queryInfo.pagenum = newPage; this.getUserList(); },
方法中具体写的是改变发起请求时的页码数的参数,再重新发起请求
作用域插槽获取对象数据
我们可以通过作用域插槽,获得每一行的对象数据。
如若代码如下:
<!-- 作用域插槽 --> <template v-slot="scope"> {{scope.row}} <!-- <el-switch v-model="scope.row.mg_state" @change="userStateChanged(scope.row)"> </el-switch> --> </template>
则显示为
在switch开关上,只绑定一个mg_state属性,便于显示状态
在change事件上,传入这一行的对象数据 ,在发起请求时,调用相应的属性参数
代码如下:
<!-- 作用域插槽 --> <template v-slot="scope"> <!-- {{scope.row}} --> <el-switch v-model="scope.row.mg_state" @change="userStateChanged(scope.row)"> </el-switch> </template>
change事件代码:
// 监听switch开关状态的改变 async userStateChanged(userinfo) { console.log(userinfo); // 模板字符串动态数据 const { data: res } = await this.$axios.put(`users/${userinfo.id}/state/${userinfo.mg_state}`); if (res.meta.status !== 200) { userinfo.mg_state = !userinfo.mg_state; return this.$message.error('更新用户状态失败!'); } this.$message.success('更新用户状态成功!'); },
在编辑、删除、分配角色按钮中,还会使用作用域插槽,方便传入对象数据的ID
以修改按钮和删除按钮为例,
<template v-slot="scope">
<!-- 修改按钮 -->
<el-button type="primary"
icon="el-icon-edit"
size="mini"
@click="showEditDialog(scope.row.id)"></el-button>
<!-- 删除按钮 -->
<el-button type="danger"
icon="el-icon-delete"
size="mini"
@click="removeUserById(scope.row.id)"></el-button>
在点击事件中传入对象数据的ID,
在编辑按钮点击事件中,发起请求获取用户信息,并显示编辑用户的对话框
// 展示编辑用户的对话框
async showEditDialog(id) {
console.log(id);
const { data: res } = await this.$axios.get('users/' + id);
if (res.meta.status !== 200) {
return this.$message.error('查询用户信息失败');
}
this.editForm = res.data;
this.editDialogVisible = true;
},
在删除按钮点击事件中,代码如下:
// 根据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.$axios.delete('users/' + id);
console.log(res);
if (res.meta.status != 200) {
return this.$message.error('删除用户失败!');
}
this.$message.success('删除用户成功!');
this.getUserList();
},
会跳出弹框询问是否删除用户数据
若确认删除,则发起delete请求删除用户数据,删除成功后,重新获取用户列表信息(刷新界面)
分配角色按钮代码如下,点击事件中传入对象数据,使用tooltip进行文字提示
<!-- 分配角色按钮 -->
<el-tooltip effect="dark"
content="分配角色"
placement="top"
:enterable="false">
<el-button type="warning"
icon="el-icon-setting"
size="mini"
@click="setRole(scope.row)"></el-button>
</el-tooltip>
搜索功能
在查出用户列表后,往往都会有搜索功能,方便进行字符串匹配搜索。
代码如下:
<!-- 搜索与添加区域 -->
<el-input placeholder="请输入内容"
v-model="queryInfo.query"
clearable
@clear="getUserList">
<template #append>
<el-button icon="el-icon-search"
@click="getUserList"></el-button>
</template>
</el-input>
在Input输入框上绑定要查找的字符串内容,这也是发起get请求获取用户列表的的一个参数,
如果查找参数为空,则返回所有用户数据,如果查找参数不为空,则返回匹配用户
clearable属性指在填入数据后,出现可以清空的按钮,clear事件是指在点击由
clearable
属性生成的清空按钮时触发(此处为获取所有用户数据)
2、添加对象(增)
2.1用户管理新增用户
管理系统中,通常的操作流程为,点击“添加”按钮,跳出一个对话框,上面有表单,点击“提交表单”按钮,增加用户成功。
在用户管理页面,代码如下:
<!-- 添加用户的对话框 -->
<el-dialog title="添加用户"
v-model="addDialogVisible"
width="50%"
@close="addDialogClosed">
<!-- 内容主体区域 -->
<el-form ref="addFormRef"
:model="addForm"
:rules="addFormRules"
label-width="70px">
<el-form-item label="用户名"
prop="username">
<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>
<!-- 底部区域 -->
<template #footer>
<span class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary"
@click="addUser">确 定</el-button>
</span>
</template>
</el-dialog>
对话框绑定的是addDialogVisible,是个布尔值,true为显示,false为不显示
事件close是指关闭对话框触发的方法。事件代码如下:
// 监听添加用户对话框的关闭事件 addDialogClosed() { this.$refs.addFormRef.resetFields(); },
需要在关闭对话框时,利用表单的索引重置表单。
对于表单来言,ref为索引,参数model动态绑定数据addForm列表,rules动态绑定校验规则。
校验规则addFormRules如下,校验规则addFormRules是一个列表的集合,每个列表的名字对应表单项的prop属性
- 每个列表中的每一项是一条校验规则
- 在第一条校验规则中,required为true代表此项必填,且会有*提示,若不符合校验规则,trigger: 'blur'是指失去焦点时触发校验,message是指若不符合的校验提示
- 在第二条校验规则中,指定字符串的最短和最长的长度,在失去焦点的时候进行校验,弱不符合会有message提示
- 关于邮箱和手机号是否符合规则的校验,是使用正则表达式来实现的,在data()函数中的var变量中,下面也会给出
addFormRules: {
username: [
{ 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' },
{ validator: checkEmail, trigger: 'blur' }
],
mobile: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ validator: checkMobile, trigger: 'blur' }
]
},
var checkEmail = (rule, value, cb) => {
// 验证邮箱的正则表达式
const regEmail = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
if (regEmail.test(value)) {
// 合法的邮箱
return cb();
}
cb(new Error('请输入合法的邮箱'));
};
// 验证手机号的规则
var checkMobile = (rule, value, cb) => {
// 验证手机号的正则表达式
const reg = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/;
if (reg.test(value)) {
cb();
} else {
cb(new Error('手机号码格式不正确'));
}
};
表单中的每个input框上绑定addForm对象的键,方便提交时发起post请求,addForm对象如下:
addForm: { username: '', password: '', email: '', mobile: '' },
- 底部区域,“取消”按钮,点击事件是直接写入“addDialogVisible = false”(把对话框消失)
- “添加”按钮,点击事件是addUser,代码如下:
在验证规则校验通过的前提下,发起添加用户post请求,是否添加成功采用$message进行提示,
之后,隐藏添加用户的对话框,并重新获取用户列表数据。
// 点击按钮添加新用户
addUser() {
this.$refs.addFormRef.validate(async valid => {
// console.log(valid);
if (!valid) return;
// 可以发起添加用户的网络请求
const { data: res } = await this.$axios.post('users', this.addForm);
if (res.meta.status != 201) {
this.$message.error('添加用户失败');
}
this.$message.success('添加用户成功');
// 隐藏添加用户的对话框
this.addDialogVisible = false;
// 重新获取用户列表数据
this.getUserList();
});
},
即点击“添加”或“取消”按钮,都会关闭添加用户的对话框,并重新获取用户列表数据(发起请求,修改绑定Table的列表数据)
注意在关闭对话框时,会触发关闭对话框的close的事件(将表单重置)
2.2 分析登录界面
登录表单界面效果如下:
我们这里主要分析表单的应用,以及按钮事件
代码如下:
<!-- 登录表单区域 -->
<el-form ref="loginFormRef"
:model="loginForm"
:rules="loginFormRules"
label-width="0px"
class="login_form">
<!-- 用户名 -->
<el-form-item prop="username">
<el-input v-model="loginForm.username"
prefix-icon="iconfont icon-user"></el-input>
</el-form-item>
<!-- 密码 -->
<el-form-item prop="password">
<el-input v-model="loginForm.password"
prefix-icon="iconfont icon-3702mima"
type="password"></el-input>
</el-form-item>
<el-form-item class="btns">
<el-button type="primary"
@click="login">登录</el-button>
<el-button type="info"
@click="resetLoginForm">重置</el-button>
</el-form-item>
</el-form>
表单索引为loginFormRef,model动态绑定数据loginForm,rules动态绑定校验规则loginFormRules
loginForm数据形式如下:
//这是登录表单的数据绑定对象
loginForm: {
username: 'admin',
password: '123456'
},
由于有初始值,在显示页面的时候就会自动填充上去。
校验规则loginFormRules如下:
// 这是表单的验证规则对象
loginFormRules: {
username: [
{ 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' }
]
}
若单击重置按钮,则是将表单清空,对应resetLoginForm事件
resetLoginForm() {
// console.log(this);
this.$refs.loginFormRef.resetFields();
},
单击登录按钮,对应login事件,
login() {
this.$refs.loginFormRef.validate(async valid => {
// console.log(valid);
if (!valid) return;
const { data: res } = await this.$axios.post('login', this.loginForm);
console.log(res);
if (res.meta.status != 200) return this.$message.error('登录失败!');
this.$message.success('登录成功!');
// 1.将登录成功后的token,保存到客户端的sessionStorage中
// 1.1项目中除了登录之外的其他API接口,必须在登录之后才能访问
// 1.2token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
window.sessionStorage.setItem('token', res.data.token);
// 2.通过编程式导航跳转到后台主页,路由地址是 /home
this.$router.push('/home');
});
}
在表单验证通过的的情况下,发起登录post请求,
若登录失败,则进行消息提醒,之后方法return出去,
若登录成功,则消息提醒登录成功,保存token,并编程式导航跳转到首页。
3、删除对象(删)
在用户管理界面中,点击删除按钮可以删除某个用户,
此处删除按钮,代码如下:
<!-- 删除按钮 -->
<el-button type="danger"
icon="el-icon-delete"
size="mini"
@click="removeUserById(scope.row.id)"></el-button>
点击事件是removeUserById,通过作用域插槽获得对象的ID
代码如下:
// 根据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.$axios.delete('users/' + id);
console.log(res);
if (res.meta.status != 200) {
return this.$message.error('删除用户失败!');
}
this.$message.success('删除用户成功!');
this.getUserList();
},
它首先会跳出一个MessageBox弹出框,询问用户是否确定删除,
使用confirmResult接收返回结果,若确认删除,则返回值为字符串confirm,若用户取消删除,则返回值为字符串cancel
若返回值为cancel,则有Message提示'已取消删除'
若返回值为confirm,则发起delete请求删除用户。
若删除失败,则有message提示'删除用户失败!'
若删除成功,则有message提示'删除用户成功!',并重新获取Table绑定的用户数据
4、修改对象(改)
<!-- 修改按钮 -->
<el-button type="primary"
icon="el-icon-edit"
size="mini"
@click="showEditDialog(scope.row.id)"></el-button>
与删除按钮类似,传入用户的ID
点击事件showEditDialog如下:
// 展示编辑用户的对话框
async showEditDialog(id) {
console.log(id);
const { data: res } = await this.$axios.get('users/' + id);
if (res.meta.status !== 200) {
return this.$message.error('查询用户信息失败');
}
this.editDialogVisible = true;
this.editForm = res.data;
},
发起get请求,获取该用户的信息,得到绑定编辑用户对话框中的表单的editForm,并显示对话框
对话框的HTML代码如下:
<!-- 修改用户的对话框 -->
<el-dialog title="修改用户"
v-model="editDialogVisible"
width="50%"
@close="editDialogClosed">
<el-form ref="editFormRef"
:model="editForm"
:rules="editFormRules"
label-width="70px">
<el-form-item label="用户名">
<el-input v-model="editForm.username"
disabled></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>
<template #footer>
<span class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary"
@click="editUserInfo">确 定</el-button>
</span>
</template>
</el-dialog>
close事件为对话框关闭触发的事件,如下:
// 监听修改用户对话框的关闭事件
editDialogClosed() {
this.$refs.editFormRef.resetFields();
},
即重置对话框中的表单。
编辑用户的表单索引是editFormRef,绑定的数据是editForm,绑定的校验规则是editFormRules
editForm数据类型如下:
editForm: {},
editFormRules校验规则如下:
// 修改表单的验证规则对象
editFormRules: {
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ validator: checkEmail, trigger: 'blur' }
],
mobile: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ validator: checkMobile, trigger: 'blur' }
]
},
与添加用户表单中类似的校验规则,
对话框的底部区域,点击取消按钮,会把对话框消失掉
点击确定按钮,对应editUserInfo事件,代码如下:
// 修改用户信息并提交
editUserInfo() {
this.$refs.editFormRef.validate(async valid => {
if (!valid) return;
// 发起修改用户信息的数据请求
const { data: res } = await this.$axios.put('users/' + this.editForm.id, {
email: this.editForm.email,
mobile: this.editForm.mobile
});
// console.log(res);
if (res.meta.status != 200) {
return this.$message.error('更新用户信息失败!');
}
// 关闭对话框
this.editDialogVisible = false;
// 刷新数据列表
this.getUserList();
// 提示修改成功
this.$message.success('更新用户信息成功!');
});
},
在校验规则通过的前提下,发起修改用户的post请求,若修改成功,则关闭对话框,重新获取数据列表,并有message提示。
总结
本文介绍了管理界面涉及到增删改查的管理操作的前端实现,主要涉及到Table、Dialog等组件的使用,可以注意到,新增用户的对话框和修改用户的对话框关闭是因为其绑定数值为false,我们要使它看到,需将其绑定数值改为true。
欢迎交流、指正!