做者:小土豆biubiubiujavascript
博客园:www.cnblogs.com/HouJiao/css
掘金:juejin.im/user/58c61b…html
微信公众号:土豆妈的碎碎念(扫码关注,一块儿吸猫,一块儿听故事,一块儿学习前端技术)前端
码字不易,点赞鼓励哟~vue
上一篇文章 Element Form表单实践(上)参照着文档将表单部份内容实践了一下。java
这篇文章将分享项目开发中的一个表单实践,最终作出来的效果大体是下面这个样子:npm
这个表单看似是比较简单的,但实际上比通常表单存在一些细节的东西须要设计和处理。element-ui
接下来就来完成这个功能。后端
首先是主页面
的实现。微信
主页面
的逻辑很是简单,直接将代码贴出来。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Element Form表单实践</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="box">
<el-form label-suffix=":" :model="form" label-width="80px" ref="form">
<el-form-item label="名称" prop="name" :rules="[{ required:true, trigger: 'blur', message: '名称是必填项' }]">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="选项">
<el-switch v-model="form.item"></el-switch>
<el-button :disabled="!form.item" type="primary" size="small">详细配置</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" size="small" @click="saveInfo">保存</el-button>
</el-form-item>
</el-form>
</div>
<script> var vm = new Vue({ el: '#box', data: { form: { name: "", item: false } }, methods: { saveInfo() { this.$refs['form'].validate((valid,failedInfo) => { if(valid){ // 提示用户 this.$message({ message: '保存成功', type: "success", center: true }); }else{ return false; } }) } } }) </script>
</body>
</html>
复制代码
这段代码中的内容都是上一篇文章中实践过的,没有什么特别须要说明的点。
详细配置页面实际上也是一个表单,咱们先来把界面中须要展现的组件画出来。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Element Form表单实践</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="box">
<el-form label-suffix=":" :model="form" label-width="80px" ref="form">
<el-form-item label="名称" prop="name" :rules="[{ required:true, trigger: 'blur', message: '名称是必填项' }]">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="选项">
<el-switch v-model="form.item"></el-switch>
<el-button :disabled="!form.item" type="primary" size="small" @click="modelVisible=true">详细配置</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" size="small" @click="saveInfo">保存</el-button>
</el-form-item>
</el-form>
<!-- 详细配置 -->
<el-dialog title="详细配置" :visible.sync="modelVisible">
<el-form ref="detailForm">
<el-form-item>
<el-checkbox label="personalInfo">我的信息</el-checkbox>
</el-form-item>
<el-form-item label="年龄">
<el-input></el-input>
</el-form-item>
<el-form-item label="身高">
<el-input></el-input>
</el-form-item>
<el-form-item>
<el-checkbox label="addressInfo">住址信息</el-checkbox>
</el-form-item>
<el-form-item label="省份">
<el-input></el-input>
</el-form-item>
<el-form-item label="城市">
<el-input></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">保存</el-button>
<el-button type="primary">重置</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
<script> var vm = new Vue({ el: '#box', data: { modelVisible: false, form: { name: "", item: false } }, methods: { saveInfo() { this.$refs['form'].validate((valid,failedInfo) => { if(valid){ // 提示用户 this.$message({ message: '保存成功', type: "success", center: true }); }else{ return false; } }) } } }) </script>
</body>
</html>
复制代码
上面这段代码主要添加了两个逻辑:弹窗组件
和弹窗内部的表单组件
。
弹窗组件使用的是element
的dialog
来实现。
主要的逻辑包含定义弹窗是否显示的data
数据modelVisible
、点击详细配置
设置弹框可见以及弹窗组件的使用。
定义弹窗是否显示的data
数据modelVisible
:
var vm = new Vue({
data: {
// 弹窗是否显示
modelVisible: false
}
})
复制代码
点击详细配置
设置弹框可见:
<!-- 点击按钮设置弹窗可见 -->
<el-button :disabled="!form.item" type="primary" size="small" @click="modelVisible=true">详细配置</el-button>
复制代码
弹框组件使用:
<el-dialog title="详细配置" :visible.sync="modelVisible">
<!-- 省略表单代码 -->
</el-dialog>
复制代码
弹窗组件的实现和使用很是简单,没有特别须要说明的点。
最后在看一下效果。
表单组件的代码以下:
<el-form ref="detailForm">
<el-form-item>
<el-checkbox label="personalInfo">我的信息</el-checkbox>
</el-form-item>
<el-form-item label="年龄">
<el-input></el-input>
</el-form-item>
<el-form-item label="身高">
<el-input></el-input>
</el-form-item>
<el-form-item>
<el-checkbox label="addressInfo">住址信息</el-checkbox>
</el-form-item>
<el-form-item label="省份">
<el-input></el-input>
</el-form-item>
<el-form-item label="城市">
<el-input></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">保存</el-button>
<el-button type="primary">重置</el-button>
</el-form-item>
</el-form>
复制代码
能够看到,表单组件的代码很是的简单,前一篇文章中实践的内容这里都尚未添加。
那接下来结合本节须要实现的这个功能添加上一节中实践过的内容。
首先第一个最重要的就是表单的model
属性,也就是表单绑定的数据。
这里咱们先定义一个简单的表单数据
。
detailConfigForm: {
personalInfo: false, // 我的信息
age:'', // 年龄
height: '', // 身高
addressInfo: true, // 住址信息
province: '', // 省份
city: '' // 城市
}
复制代码
而后将该数据绑定到表单上,同时为表单项(el-form-item)
添加model
、prop
属性。
<el-form ref="detailForm" label-width="80px" :model="detailConfigForm">
<el-form-item prop="personalInfo" >
<el-checkbox label="personalInfo" v-model="detailConfigForm.personalInfo">我的信息</el-checkbox>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input v-model="detailConfigForm.age"></el-input>
</el-form-item>
<el-form-item label="身高" prop="height">
<el-input v-model="detailConfigForm.height"></el-input>
</el-form-item>
<el-form-item prop="addressInfo">
<el-checkbox label="addressInfo" v-model="detailConfigForm.addressInfo">住址信息</el-checkbox>
</el-form-item>
<el-form-item label="省份" prop="province">
<el-input v-model="detailConfigForm.province"></el-input>
</el-form-item>
<el-form-item label="城市" prop="city">
<el-input v-model="detailConfigForm.city"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">保存</el-button>
<el-button type="primary">重置</el-button>
</el-form-item>
</el-form>
复制代码
完成后,此时在表单中填写内容已经没有问题了。
接着须要实现的功能是:将我的信息/住址信息
当作一个开关
,选中
时对应模块的控件启动
,能够正常填写内容;取消选中
时,对应的模块控件禁用
,且清空
上一次填写的内容。
那咱们知道表单项设置disabled
值就能够实现。
根据前面描述禁用
和启用
的逻辑,能够发现我的信息/住址信息
的启用
、禁用
跟表单
的禁用
、启用
恰好是相反
的逻辑。
因此目前实现的思路就是:将detailConfigForm.personalInfo
的值取反
绑定在年龄
、身高
控件的disabled
属性上;将detailConfigForm.addressInfo
的值取反
绑定在省份
、城市
控件的disabled
属性上。
这里咱们只将
我的信息
部分的逻辑实现代码贴出来
<el-form-item label="年龄" prop="age">
<el-input v-model="detailConfigForm.age" :disabled="!detailConfigForm.personalInfo"></el-input>
</el-form-item>
<el-form-item label="身高" prop="height">
<el-input v-model="detailConfigForm.height" :disabled="!detailConfigForm.personalInfo"></el-input>
</el-form-item>
复制代码
在来看下效果。
地址信息
这部分的禁用
、启用
逻辑和我的信息
是相同的,这里不在多说
那接下来要实现的功能就是取消启用清空对应控件中填写的内容
。
上一节的 Element Form表单实践(上) 中说过表单的resetFileds
方法能够重置表单。
this.refs['formName'].resetFields()
复制代码
不过该方法会重置表单中的全部属性,因此说不太符合咱们的要求。咱们只须要重置部分表单:即我的信息
取消启用时,只须要清空年龄
、身高
这两个内容便可。
解决这个问题的思路之一就是放弃使用resetFields
方法,直接给表单数据赋空值
从而清空表单内容
。
清空表单内容
这个操做是在我的信息
启用和禁用的时候执行的,即在detailConfigForm.personalInfo
值发生变化时执行的,那这个很天然的就会想到使用vue watch
属性监听detailConfigForm.personalInfo
的变化,在该值为false
的时候,给表单数据赋值为空,实现清空表单内容
。
watch: {
'detailConfigForm.personalInfo': function(val){
if(val == false){
this.detailConfigForm.age = "";
this.detailConfigForm.height = "";
}
}
},
复制代码
然而在真正的项目实践中,当取消启用我的信息
时,须要清空的表单数量不止两个,而是有多个,因此做者就放弃了这种手动赋值清空的方式。
放弃这种方式的缘由还有一个,就是表单的验证也会存在问题。
表单填写完成后,点击提交,假如我的信息没有启用,那验证时就不须要对年龄和身高进行验证,而表单的验证方法
validate
是对整个表单进行校验的方法。这几个因素是我放弃手动赋值清空方式的重要缘由。
放弃手动赋值清空表单的这种方式后,我又回归到了表单的resetFields
方法。既然还想使用resetFields
方法,惟一的办法就是作一个表单嵌套
。
这样当我的信息
取消启用时,就能够调用this.refs['personalInfoForm'].resetFields()
重置我的信息这部分的表单内容。而在整个表单提交验证的时候,也能够分别调用this.refs['personalInfoForm'].validate()
和this.refs['addressInfoForm'].validate()
分开进行验证。
那这种实现思路的第一步就是将表单的数据结构进行修改。
detailConfig: {
personalInfoConfig:{
personalInfo: false, // 我的信息
age: '', // 我的信息-年龄
height: '', // 我的信息-年龄
},
addressInfoConfig:{
addressInfo: false, // 地址信息
province: '', // 地址信息-省份
city: '' // 地址信息-城市
}
}
复制代码
接下来就须要根据这样的数据结构将el-form
表单的代码进行重写。
<el-form :model="detailConfig" ref="detailForm">
<!-- 我的信息 -->
<!-- el-form的model绑定detailConfig.personalInfoConfig -->
<el-form :model="detailConfig.personalInfoConfig" label-width="80px" lable-suffix=":" ref="personalInfoForm">
<el-form-item prop="personalInfo">
<el-checkbox label="personalInfo" v-model="detailConfig.personalInfoConfig.personalInfo">我的信息</el-checkbox>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input v-model.number="detailConfig.personalInfoConfig.age" :disabled="!detailConfig.personalInfoConfig.personalInfo"></el-input>
</el-form-item>
<el-form-item label="身高" prop="height">
<el-input v-model.number="detailConfig.personalInfoConfig.height" :disabled="!detailConfig.personalInfoConfig.personalInfo"></el-input>
</el-form-item>
</el-form>
<!-- 住址信息 -->
<!-- el-form的model绑定detailConfig.addressInfoConfig -->
<el-form :model="detailConfig.addressInfoConfig" label-width="80px" lable-suffix=":" ref="addressInfoForm">
<el-form-item prop="addressInfo">
<el-checkbox v-model="detailConfig.addressInfoConfig.addressInfo" label="addressInfo">住址信息</el-checkbox>
</el-form-item>
<el-form-item label="省份" prop="province">
<el-input v-model="detailConfig.addressInfoConfig.province" :disabled="!detailConfig.addressInfoConfig.addressInfo"></el-input>
</el-form-item>
<el-form-item label="城市" prop="city">
<el-input v-model="detailConfig.addressInfoConfig.city" :disabled="!detailConfig.addressInfoConfig.addressInfo"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">保存</el-button>
<el-button type="primary">重置</el-button>
</el-form-item>
</el-form>
复制代码
接着在修改一下watch
代码。
watch:{
"detailConfig.personalInfoConfig.personalInfo": function(personalInfo){
if(personalInfo == false){
this.$refs['personalInfoForm'].resetFields()
}
},
"detailConfig.addressInfoConfig.addressInfo": function(addressInfo){
if(addressInfo == false){
this.$refs['addressInfoForm'].resetFields()
}
}
},
复制代码
能够看到watch
代码内部就能够直接使用表单的resetFields
方法,对我的信息
和住址信息
分开进行清空。
最终的结果和手动赋值清空是同样的,这里不在演示。
最后一个就是表单的验证了。
首先咱们须要编写表单的rules
验证规则。
detailConfig: {
personalInfoConfig:{
personalInfo: false,
age: '',
height: '',
rules: {
age: [{
type: 'number',
message: '年龄必须为数字值'
}],
height: [{
type: 'number',
message: '身高必须为数字值'
}]
}
},
addressInfoConfig:{
addressInfo: false,
province: '',
city: '',
rules: {
province: [
{ min: 2, max: 10, message: '长度必须在2-10个字符'}
],
city: [
{ min: 2, max: 10, message: '长度必须在2-10个字符' }
]
}
}
}
复制代码
新增的验证规则以下:
年龄和身高:必须为数值;
省份和城市:长度必须在2-10个字符。
复制代码
接着在保存按钮的click
事件上绑定saveConfig
方法。
<el-button type="primary" @click="saveConfig">保存</el-button>
复制代码
接着编写saveConfig
的逻辑。
须要说明的是,只有对应的按钮启用了,才会对对应启用的表单作验证
saveConfig(){
// 若是我的信息启用,则须要对我的信息下的年龄、身高字段进行验证。
if(this.detailConfig.personalInfoConfig.personalInfo){
this.$refs['personalInfoForm'].validate((valid,failedInfo) => {
// 我的信息下的年龄、身高字段进行验证经过。
if(valid){
// 判断地址信息是否启用,启用的话须要对地址信息下的城市、省份进行验证
if(this.detailConfig.personalInfoConfig.personalInfo){
this.$refs['addressInfoForm'].validate((valid,failedInfo) => {
// 地址信息下的城市、省份验证成功。关闭dialog
if(valid){
this.modelVisible = false;
}else{
return false;
}
})
}else{
this.modelVisible = false;
}
}else{
return false;
}
})
// 若是地址信息启用,则须要对地址信息下的省份、城市字段进行验证。
}else if(this.detailConfig.addressInfoConfig.addressInfo){
this.$refs['addressInfoForm'].validate((valid,failedInfo) => {
if(valid){
this.modelVisible = false;
}else{
return false;
}
})
// 我的信息和地址信息均没有启用,直接关闭dialog
}else{
this.modelVisible = false;
}
},
复制代码
这部分的逻辑比较繁琐,由于存在
启用验证
、不启用就不验证
的逻辑判断
完成后,最终的效果咱们再来看一下。
首先在页面上添加剧置按钮,绑定事件。
<el-button type="primary" @click='resetForm'>重置</el-button>
复制代码
接着就来使用表单的重置方法resetFileds
来重置表单的内容。
那这里须要注意的一点就是咱们的表单是嵌套表单。
直接调用外层表单
的resetFileds
方法没有办法去重置表单内容。所以这里必须调用内层表单的resetFileds
方法。
resetForm(formName){
this.$refs['personalInfoForm'].resetFields();
this.$refs['addressInfoForm'].resetFields();
// 调用外层表单的`resetFileds`方法没有办法去重置表单内容
// this.$refs['detailForm'].resetFields();
}
复制代码
表单重置这里就不贴演示结果了
到这里咱们表单的大部分功能已经实现了:表单禁用启用
、表单禁用时清空表单内容
、表单验证
、表单重置
。
那接下来就须要对实现的这个功能进行在思考。
第一个是功能优化。
回头看全部实现的功能,惟一以为不太合适的地方就是表单的验证逻辑。
saveConfig(){
// 若是我的信息启用,则须要对我的信息下的年龄、身高字段进行验证。
if(this.detailConfig.personalInfoConfig.personalInfo){
this.$refs['personalInfoForm'].validate((valid,failedInfo) => {
// 我的信息下的年龄、身高字段进行验证经过。
if(valid){
// 判断地址信息是否启用,启用的话须要对地址信息下的城市、省份进行验证
if(this.detailConfig.addressInfoConfig.addressInfo){
this.$refs['addressInfoForm'].validate((valid,failedInfo) => {
// 地址信息下的城市、省份验证成功。关闭dialog
if(valid){
this.modelVisible = false;
}else{
return false;
}
})
}else{
this.modelVisible = false;
}
}else{
return false;
}
})
// 若是地址信息启用,则须要对地址信息下的省份、城市字段进行验证。
}else if(this.detailConfig.addressInfoConfig.addressInfo){
this.$refs['addressInfoForm'].validate((valid,failedInfo) => {
if(valid){
this.modelVisible = false;
}else{
return false;
}
})
// 我的信息和地址信息均没有启用,直接关闭dialog
}else{
this.modelVisible = false;
}
}
复制代码
能够看到这里有多层嵌套的逻辑判断。
那这个验证功能无非就是但愿当前不选中那一项就不验证那一项,那能不能将校验规则定义为动态的,不选中时移除
校验规则,选中时添加
上校验规则。
那么答案是能够的,因此接下来就来实现一下。
首先咱们在data
数据中定义多个规则。
personalInfoConfig:{
personalInfo: false,
age: '',
height: '',
rules: {
age: [{
type: 'number',
message: '年龄必须为数字值'
}],
height: [{
type: 'number',
message: '身高必须为数字值'
}]
},
// 定义空的验证规则
emptyRules: {}
},
addressInfoConfig:{
addressInfo: false,
province: '',
city: '',
rules: {
province: [
{ min: 2, max: 10, message: '长度必须在2-10个字符'}
],
city: [
{ min: 2, max: 10, message: '长度必须在2-10个字符' }
]
},
// 定义空的验证规则
emptyRules: {}
}
复制代码
即一个正常的验证规则,对应复选框启用时的验证;还要一个空的验证规则,对应复选框取消启用时的验证。
而后咱们将规则定义到计算属性
中。
computed:{
personalInfoRules: function(){
if(this.detailConfig.personalInfoConfig.personalInfo == true){
return this.detailConfig.personalInfoConfig.rules;
}else{
return this.detailConfig.personalInfoConfig.emptyRules;
}
},
addressInfoRules: function(){
if(this.detailConfig.addressInfoConfig.addressInfo == true){
return this.detailConfig.addressInfoConfig.rules;
}else{
return this.detailConfig.addressInfoConfig.emptyRules;
}
}
},
复制代码
接着就是将计算属性
绑定到对应表单的rules
属性上。
<!-- 我的信息 -->
<el-form :model="detailConfig.personalInfoConfig" label-width="80px" lable-suffix=":" ref="personalInfoForm" :rules="personalInfoRules">
<!-- 省略 -->
</el-form>
<!-- 住址信息 -->
<el-form :model="detailConfig.personalInfoConfig" label-width="80px" lable-suffix=":" ref="personalInfoForm" :rules="personalInfoRules">
<!-- 省略 -->
</el-form>
复制代码
能够看到el-form
上绑定的rules
已经修改成computed
中定义的属性了。
这样的改动完成以后,最后一步就是重写校验逻辑了。
saveConfig(){
this.$refs['personalInfoForm'].validate((valid,failedInfo) => {
// 我的信息下的年龄、身高字段进行验证经过。
if(valid){
this.$refs['addressInfoForm'].validate((valid,failedInfo) => {
// 地址信息下的城市、省份验证成功,关闭dialog
if(valid){
this.modelVisible = false;
}else{
return false;
}
})
}else{
return false;
}
})
},
复制代码
由于规则在动态的变化,而验证的逻辑就不须要复选框的启用禁用进行判断,直接使用规则进行验证便可。因此的验证逻辑是否是就清爽了不少。
那这个就是针对表单验证作的一个小小的优化。 若是你们有更好的方法能够分享给我
在功能测试的过程当中,我还发现一个问题。
当我在表单中填写了错误格式的数据后,直接经过点击弹窗上方的叉号按钮来关闭dialog
(不点击保存按钮),那此时detailConfig
中的字段值已是那个错误格式的数据(双向数据绑定原理),若是直接将最终的detailConfig
发送到后端显然是不对的。
目前暂时尚未一个好的解决思路,正在思考中,欢迎你们和我交流。
最后我将本次实践的完整代码贴在这里。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Element Form表单实践</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="box">
<el-form label-suffix=":" :model="form" label-width="80px" ref="form">
<el-form-item label="名称" prop="name" :rules="[{ required:true, trigger: 'blur', message: '名称是必填项' }]">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="选项">
<el-switch v-model="form.item"></el-switch>
<el-button :disabled="!form.item" type="primary" size="small" @click="modelVisible=true">详细配置</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" size="small" @click="saveInfo">保存</el-button>
</el-form-item>
</el-form>
<!-- 详细配置 -->
<el-dialog title="详细配置" :visible.sync="modelVisible">
<el-form :model="detailConfig" ref="detailForm">
<el-form :model="detailConfig.personalInfoConfig" label-width="80px" lable-suffix=":" ref="personalInfoForm" :rules="personalInfoRules">
<el-form-item prop="personalInfo">
<el-checkbox label="personalInfo" v-model="detailConfig.personalInfoConfig.personalInfo">我的信息</el-checkbox>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input v-model.number="detailConfig.personalInfoConfig.age" :disabled="!detailConfig.personalInfoConfig.personalInfo"></el-input>
</el-form-item>
<el-form-item label="身高" prop="height">
<el-input v-model.number="detailConfig.personalInfoConfig.height" :disabled="!detailConfig.personalInfoConfig.personalInfo"></el-input>
</el-form-item>
</el-form>
<el-form :model="detailConfig.addressInfoConfig" label-width="80px" lable-suffix=":" ref="addressInfoForm" :rules="addressInfoRules">
<el-form-item prop="addressInfo">
<el-checkbox v-model="detailConfig.addressInfoConfig.addressInfo" label="addressInfo">住址信息</el-checkbox>
</el-form-item>
<el-form-item label="省份" prop="province">
<el-input v-model="detailConfig.addressInfoConfig.province" :disabled="!detailConfig.addressInfoConfig.addressInfo"></el-input>
</el-form-item>
<el-form-item label="城市" prop="city">
<el-input v-model="detailConfig.addressInfoConfig.city" :disabled="!detailConfig.addressInfoConfig.addressInfo"></el-input>
</el-form-item>
</el-form>
<el-form-item>
<el-button type="primary" @click="saveConfig">保存</el-button>
<el-button type="primary" @click='resetForm'>重置</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
<script> var vm = new Vue({ el: '#box', computed:{ personalInfoRules: function(){ if(this.detailConfig.personalInfoConfig.personalInfo == true){ return this.detailConfig.personalInfoConfig.rules; }else{ return this.detailConfig.personalInfoConfig.emptyRules; } }, addressInfoRules: function(){ if(this.detailConfig.addressInfoConfig.addressInfo == true){ return this.detailConfig.addressInfoConfig.rules; }else{ return this.detailConfig.addressInfoConfig.emptyRules; } } }, watch:{ "detailConfig.personalInfoConfig.personalInfo": function(personalInfo){ if(personalInfo == false){ this.$refs['personalInfoForm'].resetFields() } }, "detailConfig.addressInfoConfig.addressInfo": function(addressInfo){ if(addressInfo == false){ this.$refs['addressInfoForm'].resetFields() } } }, data: { form: { name: "", item: false }, modelVisible: false, detailConfig: { personalInfoConfig:{ personalInfo: false, age: '', height: '', rules: { age: [{ type: 'number', message: '年龄必须为数字值' }], height: [{ type: 'number', message: '身高必须为数字值' }] }, // 定义空的验证规则 emptyRules: {} }, addressInfoConfig:{ addressInfo: false, province: '', city: '', rules: { province: [ { min: 2, max: 10, message: '长度必须在2-10个字符'} ], city: [ { min: 2, max: 10, message: '长度必须在2-10个字符' } ] }, // 定义空的验证规则 emptyRules: {} } } }, methods: { saveInfo() { this.$refs['form'].validate((valid,failedInfo) => { if(valid){ // 将表单数据组合到一块儿 // 这样方式比较简单,不过会将数据中的rules传递到后端 let data = { ...this.detailConfig, ...this.form } // 将数据发送到后端 // 代码省略...... // 数据保存成功提示用户 this.$message({ message: '保存成功', type: "success", center: true }); }else{ return false; } }) }, saveConfig(){ this.$refs['personalInfoForm'].validate((valid,failedInfo) => { // 我的信息下的年龄、身高字段进行验证经过。 if(valid){ this.$refs['addressInfoForm'].validate((valid,failedInfo) => { // 地址信息下的城市、省份验证成功。关闭dialog if(valid){ this.modelVisible = false; }else{ return false; } }) }else{ return false; } }) }, resetForm(formName){ this.$refs['personalInfoForm'].resetFields(); this.$refs['addressInfoForm'].resetFields(); // 调用外层表单的`resetFileds`方法没有办法去重置表单内容 // this.$refs['detailForm'].resetFields(); } } }) </script>
</body>
</html>
复制代码
注意在主页面保存整个表单内容是,我使用ES6的
展开运算符
将主页面的表单数据和弹框组件内的表单数据合并到了一块儿,这样就能够直接将合并后的数据发送到后端。 使用展开运算符合并数据虽然比较方便,可是定义的验证规则数据也会包含在最终的结果中。
做者实现的这个功能是在一个原本完整的表单提交功能上新增的一个小功能。当时已经完成的表单的数据结构是根据业务和逻辑设计的多层嵌套字典,因此后面我新增
的这个数据结构
也是嵌套在字典里层的。
// 这个数据是根据业务逻辑设计的多层嵌套字典
people{
// 这里还有别的表单的数据
// config是我新增的表单数据
config:{
icmpconfig:{
time:10
},
tcpconfig:{
time:10
}
}
}
复制代码
可是刚一开始我并无作表单嵌套,而是在外层使用单个的el-form
实现。
到后面作验证添加rules
的时候,prop
的值就得写成people.icmpconfig.time
,但实际是prop
是不能写成这样.
的形式,写了以后会报错说time
没有定义。
介于这个缘由,在综合前面的说法:
是一整个使用表单嵌套的缘由。
使用表单嵌套感受有利也有弊,方便了一些逻辑,也带来了一些问题。
因此必定要提早设计好,选择一个合理的实现方式。
小土豆biubiubiu
一个努力学习的前端小菜鸟,知识是无限的。坚信只要不停下学习的脚步,总能到达本身指望的地方
同时仍是一个喜欢小猫咪的人,家里有一只美短小母猫,名叫土豆
土豆妈的碎碎念
微信公众号的初衷是记录本身和身边的一些故事,同时会不按期更新一些技术文章
欢迎你们扫码关注,一块儿吸猫,一块儿听故事,一块儿学习前端技术
小小总结,欢迎你们指导~