【VUE的Form表单】使用v-if切换控件时,表单校验不生效
背景
这几天在开发管理端表单,有一个有效期限类型是否固定期限
的单选按钮,对应控制切换有效期限的日期范围选择 和 期限说明,最后的表单如下:
两个都是必填,点击提交校验都要生效
原始代码
- 表单部分代码
<a-form-model ref="form" :model="mdl">
<a-row>
<!-- 有效期限类型 -->
<a-col :span="12">
<a-form-model-item
label="有效期限类型"
prop="expirationType"
:rules="{ required: true, message: '请输入有效期限类型', trigger: ['blur', 'change'] }"
>
<a-radio-group
v-for="item in expirationTypeList"
:key="item.value"
v-model="mdl.expirationType"
:disabled="false"
>
<a-radio :value="item.value">
{{ item.name }}
</a-radio>
</a-radio-group>
</a-form-model-item>
</a-col>
<!-- 有效期限 -->
<a-col :span="12">
<a-form-model-item
label="有效期限"
v-if="mdl.expirationType != 'WITHOUT'"
:rules="{ required: true, message: '请输入有效期限.', trigger: ['blur', 'change'] }"
>
<a-form-model-item
:rules="{ required: true, message: '请输入有效期限开始时间', trigger: ['blur', 'change'] }"
prop="expirationStartTime"
:style="{ display: 'inline-block', width: 'calc(50% - 12px)', marginBottom: '0px' }"
>
<a-date-picker
:disabled-date="(start) => DateUtil.validate(start, mdl.expirationEndTime)"
placeholder="开始时间"
v-model="mdl.expirationStartTime"
format="YYYY-MM-DD"
:disabled="false"
/>
</a-form-model-item>
<span :style="{ display: 'inline-block', width: '24px', textAlign: 'center' }"> 至 </span>
<a-form-model-item
:rules="{ required: true, message: '请输入有效期限结束时间', trigger: ['blur', 'change'] }"
prop="expirationEndTime"
:style="{ display: 'inline-block', width: 'calc(50% - 12px)', marginBottom: '0px' }"
>
<a-date-picker
:disabled-date="(end) => DateUtil.validate(mdl.expirationStartTime, end)"
placeholder="结束时间"
v-model="mdl.expirationEndTime"
format="YYYY-MM-DD"
:disabled="false"
/>
</a-form-model-item>
</a-form-model-item>
<a-form-model-item
v-if="mdl.expirationType == 'WITHOUT'"
label="期限说明"
prop="expirationExplain"
:rules="{ required: true, message: '请输入期限说明.', trigger: ['blur', 'change'] }"
>
<a-input
placeholder="请输入期限说明"
v-model="mdl.expirationExplain"
:maxLength="50"
:disabled="false"
/>
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
- 最后提交保存部分代码(这部分代码最后是不需要动的)
save(){
// 最后点击提交时会对表单整体做一次校验
this.$refs.form.validate((res, object) => {
if (!res) {
// 未通过校验:给出整体的提示
this_.$message.error('请根据提示信息补全提交的内容信息')
// 关闭提交,重新填写数据
...
} else {
// 校验通过,正常调接口保存数据
...
}
})
}
上述代码出现的问题
我在切换 有效期限类型之后,点击
提交
,表单未对其添加校验,没有填写数据必填校验也通过了,最后尝试了v-show
也还是不行,发现他的校验一直存在,即时没显示该控件
原因:
【1】使用
v-if
:ant
design在对form表单中带有prop属性
的子组件进行校验规则绑定时,是在vue声明周期mounted
完成的。而v-if
用来切换的元素是会被销毁的,导致了v-if内的表单项,由于在mounted时期没有进行渲染,所以规则也没有绑定上,因此初始化时不符合显示条件的不会生成规则,导致后面切换条件,显示的输入框的校验不会生效。
【2】使用v-show
:初始化时会生成所有的规则,即使隐藏了也会进行规则校验。
解决方案:
给设置 v-if 的元素加上 key
值,如下所示:
<a-row>
//<!--有效期限类型 -->
<a-col :span="12">
<a-form-model-item
label="有效期限类型"
prop="expirationType"
:rules="{ required: true, message: '请输入有效期限类型', trigger: ['blur', 'change'] }"
>
<a-radio-group v-model="mdl.expirationType" @change="expirationTypeChange">
<a-radio v-for="item in expirationTypeList" :key="item.value" :value="item.value">
{{ item.name }}
</a-radio>
</a-radio-group>
</a-form-model-item>
</a-col>
<!-- 9、有效期限 -->
<a-col :span="12">
<a-form-model-item
label="有效期限"
v-if="mdl.expirationType != 'WITHOUT'"
:rules="{ required: true, message: '', trigger: ['blur', 'change'] }"
style="margin-bottom: 0px"
>
<a-form-model-item
:rules="{ required: true, message: '请输入有效期限开始时间', trigger: ['blur', 'change'] }"
prop="expirationStartTime"
key="expirationStartTime"
:style="{ display: 'inline-block', width: 'calc(50% - 12px)' }"
>
<a-date-picker
:disabled-date="(start) => DateUtil.validate(start, mdl.expirationEndTime)"
placeholder="开始时间"
v-model="mdl.expirationStartTime"
:format="dateFormat"
:valueFormat="dateFormat"
:disabled="false"
/>
</a-form-model-item>
<span :style="{ display: 'inline-block', width: '24px', textAlign: 'center' }"> 至 </span>
<a-form-model-item
:rules="{ required: true, message: '请输入有效期限结束时间', trigger: ['blur', 'change'] }"
prop="expirationEndTime"
key="expirationEndTime"
:style="{ display: 'inline-block', width: 'calc(50% - 12px)' }"
>
<a-date-picker
:disabled-date="(end) => DateUtil.validate(mdl.expirationStartTime, end)"
placeholder="结束时间"
v-model="mdl.expirationEndTime"
:format="dateFormat"
:valueFormat="dateFormat"
:disabled="false"
/>
</a-form-model-item>
</a-form-model-item>
<a-form-model-item
v-if="mdl.expirationType == 'WITHOUT'"
label="期限说明"
prop="expirationExplain"
key="expirationExplain"
:rules="{ required: true, message: '请输入期限说明.', trigger: ['blur', 'change'] }"
>
<a-input
placeholder="请输入期限说明"
v-model="mdl.expirationExplain"
:maxLength="50"
:disabled="false"
/>
</a-form-model-item>
</a-col>
</a-row>
最后呢,还添加了一个切换有效期限类型, 有效期限 和 期限说明 数据清空
的功能,我在网上查了,在控件
(例如 a-input)上绑定key值
,v-if切换的时候,对应的数据会清空
,但是呢,我们上边为了表单校验在a-form-model-item
组件上绑定了key值
,现在如果再在控件上去绑定key,v-if切换之后,控件上会无法填写数据,所以只能利用普通的js
手动去切换清空数据:
利用 a-radio-group
的change属性API,代码如下:
// 期限类型切换
expirationTypeChange() {
this.qualification.expirationStartTime ? (this.qualification.expirationStartTime = null) : ''
this.qualification.expirationEndTime ? (this.qualification.expirationEndTime = null) : ''
this.qualification.expirationExplain ? (this.qualification.expirationExplain = null) : ''
},
最后总结
通过这次各种查看其他文章,我发现 key值 在vue中的作用挺大的,之后我也会整理出一篇比较全面的博客出来,各位敬请期待哦!!!
还有,对于上面的问题,各位如果有更好的办法,欢迎评论区指导哦!