el-form表单验证
form表单由输入框、选择器、单选框、多选框、开关等控件组成,用以收集、校验、提交数据。
表单验证可以在防止用户犯错的前提下,尽可能让用户更早地发现并纠正错误。Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。
一、rules的两种写法
1.写在<el-for-item>标签里
<el-form-item
:rules="[{required: true, message: '请输入姓名', trigger: 'blur'}]"
class="form-item"
label="姓名:"
prop="name"
label-width="85px">
<el-input v-model="formData.name" type="text" size="small"></el-input>
</el-form-item>
<el-form-item
:rules="[{required: true, message: '请输入年龄', trigger: 'blur'}]"
class="form-item" label="年龄:"
prop="age"
label-width="85px">
<el-input v-model="formData.age" type="text" size="small"></el-input>
</el-form-item>
2.写在data里
<el-form ref="formRef" :model="formData" :rules="formRules" class="form">
<el-form-item class="form-item" label="姓名:" prop="name" label-width="85px">
<el-input v-model="formData.name" type="text" size="small"></el-input>
</el-form-item>
<el-form-item class="form-item" label="年龄:" prop="age" label-width="85px">
<el-input v-model="formData.age" type="text" size="small"></el-input>
</el-form-item>
</el-form>
data() {
return {
type: 0,
formData: {
name: '',
age: ''
},
formRules: {
name: [{required: true, message: '请输入姓名', trigger: 'blur'}],
time: [{required: true, message: '请选择时间', trigger: 'blur'}]
}
}
}
二、校验规则
规则 | 说明 |
---|---|
required | 如果为true,表示该字段必填 |
message | 当不满足设置的规则时的提示信息 |
pattern | 正则表达式,通过正则表达式验证值是否合规 |
min | 当值为字符串时,min表示字符串的最小长度;当值为数字时,min表示数组的最小值 |
max | 当值为字符串时,max表示字符串的最大长度;当值为数字时,max表示数组的最大值 |
trigger | 校验的触发方式,change(值改变)/blur(失去焦点)两种 |
validator | 如果配置型的校验规则满足你的需求,可以通过自定义函数来完成校验 |
1.自定义校验规则
validator是一个函数, 其中有三个参数 (rule(当前规则),value(当前值),callback(回调函数))
var func = function (rule, value, callback) {
// 根据value进行进行校验
// 如果一切ok
// 直接执行callback
callback() // 一切ok 请继续
// 如果不ok
callback(new Error("错误信息"))
}
例如:
const validatePassword2 = (rule, value, callback) => {
if (value !== '' && value !== this.formData.newPassword && value) {
callback(new Error('两次输入密码不一致!'))
else {
callback()
}
}
注意: 自定义校验规则的时候,必须保证各个分支且至少有一个分支执行 callback() 函数,否则会导致表单校验操作 validate 阻塞而无返回结果。
2.手动校验
对表单进行完整或部分校验的API
<el-form ref="formRef" :model="formData" :rules="formRules" label-position="right" class="m-form" label-width="120px">
this.{refs['formRef'].validate(valid => {
if (!valid) return // 校验不通过
// 校验通过
// 执行后续代码
})
三、注意事项
- 如果要使用rules进行表单校验,<el-form>标签必须要通过:model=‘formData’绑定,不能使用v-model
- <el-form-item>标签的prop属性必须要与标签中需要验证的值的参数名一样,且要含在传入Form组件的model中的值里面,否则会导致校验不通过。
- 多表单校验
el-form-item 内部如果包含多个表单,默认校验失败时会将所有表单高亮,例如:
<el-form-item class="form-item" label="执行时间:" prop="time" label-width="85px" required>
<el-select v-model="formData.time" clearable>
<el-option label="时" value="hour">时</el-option>
<el-option label="日" value="day">日</el-option>
<el-option label="周" value="week">周</el-option>
</el-select>
<el-date-picker v-model="formData.date"></el-date-picker>
</el-form-item>
虽然只有第二个表单没有输入,但是校验失败时会同时高亮两个表单。
解决办法:嵌套
外层 el-form-item 是正常的信息,内层对第二个表单再次嵌套 el-form-item 指定校验属性:
<el-form-item class="form-item" label="执行时间:" label-width="85px" required>
<el-form-item class="form-item" prop="time" required>
<el-select v-model="formData.time" clearable>
<el-option label="时" value="hour">时</el-option>
<el-option label="日" value="day">日</el-option>
<el-option label="周" value="week">周</el-option>
</el-select>
</el-form-item>
<el-date-picker v-model="formData.date"></el-date-picker>
</el-form-item>
将日期输入框包裹在新的 el-form-item 中,外层的 el-form-item 添加 requred 显示前面的红星,就可以只对该属性校验了,将第二个表单再嵌套后,校验结果就正常了:
4.复杂属性
<el-form-item class="form-item" label="配置权限:" prop="config.permission" label-width="85px">
<el-input v-model="formData.config.permission"></el-input>
</el-form-item>
该属性的rules定义也必须是对象
formRules: {
name: [{required: true, message: '请输入姓名', trigger: 'blur'}],
config: {
permission: [{required: true, message: '请输入配置权限', trigger: 'blur'}]
}
}
5.v-if控制的表单不触发校验,v-show控制的表单在隐藏的情况下也会触发校验
添加v-if后,始化时组未被创建,校验规则也没有绑定,表单校验不生效。而添加v-show后,初始化时会生成所有的规则,所以即使隐藏了也会进行规则校验。
<el-form ref="formRef" :model="formData" :rules="formRules" class="form">
<el-form-item label="选择时间:" v-if="type === 0" prop="time">
<el-date-picker v-model="formData.time" placeholder="选择时间"></el-date-picker>
</el-form-item>
<el-form-item label="选择日期:" v-show="type === 1" prop="data">
<el-input v-model="form.date" placeholder="调度日期"></el-input>
</el-form-item>
</el-form>
formRules: {
time: [{required: true, message: '请选择时间', trigger: 'blur'}],
date: [{required: true, message: '请选择日期', trigger: 'blur'}],
}
初始化时第一个“选择时间”表单如果没有,那么当它重新生成时,上面的校验无效。第二个“选择日期”表单如果没有,校验时仍然会触发校验。
解决办法:使用 v-show/v-if 控制显示和隐藏,同时为它们的给 el-form-item 元素添加不同的 key 属性值。如果v-if渲染的目标是整个表单,则在form标签写入key。也可以将校验规则写进:rules="[{key: value,...}]"中。
// 添加key值
<el-form ref="formRef" :model="formData" :rules="formRules" class="form">
<el-form-item label="选择时间:" v-if="type === 0" prop="time" key="time">
<el-date-picker v-model="formData.time" placeholder="选择时间"></el-date-picker>
</el-form-item>
// 将校验规则写进:rules="[{key:value,...}]"
<el-form-item label="选择日期:" v-show="type === 1" prop="date"" :rules="[{required: true, message: '请选择日期', trigger: 'blur'}]">
<el-input v-model="form.date" placeholder="调度日期"></el-input>
</el-form-item>
</el-form>
注意:动态显示隐藏的表单切换后,应该清空上次的表单校验结果:this.{refs.formRef.clearValidate('xxx');
否则相同位置的校验结果会混乱的。