现在有这样一个变态的需求吧,在elementUI表单校验中,所有空值校验在用户点击“确定”按钮时才触发,失去焦点时只有有值,才进行其它有效性校验;
也就是说,必填项为空,我失去焦点,是不能给出提示的,表单也不能标红;失去焦点只能校验其他规则,比如邮箱格式,手机号格式等;当我点击提交或确定按钮,所有的为空的表单给出提示,且标红。
下图为效果图:
如果你看过elementUI底层源码,你就知道这个校验规则是用的第三方开源库,async-validator
当你在规则中写入{ required: true, trigger: ‘blur’ }
他还是会有提示信息。 这时候你会发现是不能进行通过改底层代码来实现这个特殊的需求。
下面介绍一下如何实现:
方式一: 简便,适合复杂表单
思路: 在表单元素input标签或者其他绑定v-model的标签上加入
:validate-event="这里写三目运行进行设置为true还是false"
false代表不校验,true代表检验
具体代码如下:
<el-form :model="form" ref="form" label-width="100px" class="demo-dynamic">
<el-form-item
prop="email"
label="邮箱"
:rules="[
{ required: true, message: '请输入邮箱地址', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
]"
>
<el-input v-model="form.email" :validate-event="form.email==''?false:true"></el-input>
</el-form-item>
<el-form-item
label="域名"
prop="domains"
:rules="{
required: true, message: '域名不能为空', trigger: 'blur'
}"
>
<el-input v-model="form.domains" :validate-event="form.domains==''?false:true"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm1('form')">提交</el-button>
<el-button @click="resetForm1('form')">重置</el-button>
</el-form-item>
</el-form>
Input上需要加上述特殊属性,
日期组件需要加特殊属性, 校验规则中的触发事件必须设置为blur
其他控件如el-select、多选组件等他们需要把校验规则中的触发事件设置为blur。
注意: 这个属性不是所有的控件都有,目前发现的是,只有input、日期组件是有这个属性的。
方式二: 比较繁琐
1、 从失去焦点入手,给表单元素绑定失去焦点方法
2、给el-form-item动态绑定class
3、失去焦点的时候,判断如果此时为空,就添加动态类名,否则动态类名为空;需要注意的是:在提交方法中,把“表单是否增加类名,默认都为否” 还原
4、编写覆盖的样式
具体代码:
html部分
<el-form :model="dynamicValidateForm" ref="dynamicValidateForm" label-width="100px" class="demo-dynamic">
<el-form-item
:class="[formMessage.email? 'isNotError':'']"
prop="email"
label="邮箱"
:rules="[
{ required: true, message: '请输入邮箱地址', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
]"
>
<el-input v-model="dynamicValidateForm.email" @blur="blurEmail"></el-input>
</el-form-item>
<el-form-item
:class="[formMessage.domains? 'isNotError':'']"
label="域名"
prop="domains"
:rules="{
required: true, message: '域名不能为空', trigger: 'blur'
}"
>
<el-input v-model="dynamicValidateForm.domain" @blur="blurDomains"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('dynamicValidateForm')">提交</ai-button>
<el-button @click="resetForm('dynamicValidateForm')">重置</el-button>
</el-form-item>
</el-form>
数据定义部分:
data() {
return {
dynamicValidateForm: { // 表单数据定义
domains: "",
email: ''
},
formMessage:{ // 表单是否增加类名,默认都为否
email:false,
domains:false
}
};
},
方法:
blurEmail(val){
val.target.value ? this.formMessage.email = false :this.formMessage.email = true
},
blurDomains(val){
val.target.value>0 ? this.formMessage.domains = false :this.formMessage.domains = true
},
submitForm(formName) {
this.formMessage={
email:false,
domains:false
}
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
样式:
<style lang="scss" scoped>
/deep/.el-form-item.is-error.isNotError .el-input__inner{
border: 1px solid #DCDFE6;
}
/deep/.el-form-item.is-error.isNotError{
.el-form-item__error{
display: none !important;
}
}
</style>
总结:针对表单验证这次需求,上述两种方式都有不完美的地方,第一种样式覆盖,表单内容太多,写代码也会很多(有几个表单内容,就要写几个失去焦点的方法,方法里面都只有一行三目运算方法)。 第二种方式,细节注意更多,不是所有控件都有这个特殊属性,没有这个属性的,也有可能会达不到需求的效果,如果达不到需求要求效果,就需要结合第一种形式。