el-form表单验证

2023-12-25 09:46 秦倩 725

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 // 校验不通过
  // 校验通过
  // 执行后续代码
})

三、注意事项

  1. 如果要使用rules进行表单校验,<el-form>标签必须要通过:model=‘formData’绑定,不能使用v-model
  2. <el-form-item>标签的prop属性必须要与标签中需要验证的值的参数名一样,且要含在传入Form组件的model中的值里面,否则会导致校验不通过。
  3. 多表单校验

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');

否则相同位置的校验结果会混乱的。