前言:element-ui 的表单用起来实在是太僵硬了,组长便让我去看一看VeeValidate的表单验证系统,粗略看了一下官方文档,确实要灵活好用很多,便在此记录一下用法
特点
无需使用v-model将input与变量绑定(但想的话也可以),而是使用v-bind与对应的field绑定。最后直接通过form的value读取。
💡 导入npm install --save vee-validate@next
import { Form, Field, ErrorMessage } from 'vee-validate';
官方文档:VeeValidate: Painless Vue.js forms (logaretm.com)
基础用法示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <script lang ="ts" setup > import { Form , Field , ErrorMessage } from 'vee-validate' ;const validateEmail = (value: any ) => { return /@/ .test (value) ? true : '邮箱格式错误' } const isRequired =(value:string )=> { if (value && value.trim ()) { return true ; } return '你没通过捏' ; } const onSubmit = (values ) => { console .log (values) alert ('验证通过时执行' ) } </script > <template > <Form @submit ="onSubmit" > <Field name ="username" :rules ="isRequired" :validate-on-input ="true" #default ="{ errorMessage, field }" > <input v-bind ="field" type ="text" /> <p > {{ errorMessage }}</p > </Field > <button > 提交</button > <button > 提交</button > </Form > </template >
使用自定义输入框 1 2 3 4 5 6 <Form > <Field name ="username" :rules ="{ email: true }" #default ="{ errorMessage, value }" > //自定义组件推荐使用update:modelValue事件实现与Field的绑定 <CustomInput :modelValue ="value" @update:modelValue ="handleChange" /> </Field > </Form >
验证规则绑定 声明验证规则 验证规则有两种,一是直接使用函数,还有一种叫validator(个人感觉和函数区别也不大)
使用函数 声明一个函数,返回值是 bool或string 。return true 时errormessage为空, return false则errormessage为默认值, return string 则将该string赋值给errormessage。
1 2 3 4 5 6 const isRequired = (value ) => { if (value && value.trim ()) { return true ; } return 'This is required' ; }
之后使用:rules绑定
<Field name="field" :rules="isRequired" />
使用validator 声明一个validator, 类似函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import { defineRule } from 'vee-validate' ;defineRule ('required' , (value :string ) => { if (!value || !value.length ) { return 'This field is required' ; } return true ; }); defineRule ('minLength' , (value, [limit] ) => { if (!value || !value.length ) { return true ; } if (value.length < limit) { return `This field must be at least ${limit} characters` ; } return true ; }); defineRule ('minMax' , (value, [min, max] ) => { if (!value || !value.length ) { return true ; } if (value.length < min) { return `This field must be at least ${min} characters` ; } if (value.length > max) { return `This field must be at most ${max} characters` ; } return true ; });
而后用:rules绑定
绑定单个<Field name="username3" :rules="'resquired'" >
绑定多个<Field name="username3" :rules="'resquired|email'" >
绑定带参数的validator <Field name="username3" :rules="'resquired|minLength:8'" >
绑定带多个参数的validator <Field name="username3" :rules="'minMax:5,8|resquired'" >
绑定规则 除每个field单独绑定外,还可定义一个schema控制所有rules后通过name分配rule
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <template> <!-- 给Form 绑定schema --> <Form @submit ="submit" :validation-schema ="schema" v-slot ="{ errors }" > <Field name ="email" /> <span > {{ errors.email }}</span > <Field name ="password" type ="password" /> <span > {{ errors.password }}</span > <button > Submit</button > </Form > </template> <script setup > import { Form , Field } from 'vee-validate' ;const schema = { email : 'required|email' , password : 'required|minLength:8' , }; </script >
验证时机的设置 单一Field验证: 1 2 3 4 5 <Field name ="username" :rules ="{ email: true }" :validateOnInput ="true" #default ="{ errorMessage, field }" > <input v-bind ="field" type ="text" /> <p > {{ errorMessage }}</p > <button > </button > </Field >
与时机有关的prop
默认值
介绍
validateOnMount
false
validateOnInput
false
validateOnChange
true
validateOnBlur
true
validateOnModelUpdate
true
bails
true
绑定多个验证规则时,有一个验证规则未通过,直接结束验证,而不再继续验证其他规则
全表验证: 除最后的提交之外,可能还有其他地方也需要进行全表验证,VeeValidate为此提供了validate模块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <template > <Form @submit ="onSubmit" #default ="{ validate }" > <Field name ="username1" :rules ="isRequired" #default ="{ errorMessage, field}" > <input v-bind ="field" type ="text" /> <p > {{ errorMessage }}</p > </Field > <Field name ="username2" :rules ="isRequired" #default ="{ errorMessage, field }" > <input v-bind ="field" type ="text" /> <p > {{ errorMessage }}</p > </Field > <div @click ="validate()" > 11111</div > </Form > </template >
状态管理(trigger) 1 2 3 4 5 6 7 8 9 10 <!-- 验证状态管理 --> <Form @submit ="onSubmit" #default ="{ meta }" > <div > {{ meta }}</div > </Form > meta.value .initialValues ; meta.value .touched ; meta.value .pending ; meta.value .valid ; meta.value .dirty ;
1 2 3 <v-form :validation-schema ="schema" @submit ="onSubmit" v-slot ="{ isSubmitting }" >
Field 1 2 3 4 5 <Field name ="email" type ="email" :rules ="validateEmail" v-slot ="{ field, meta }" > <input v-bind ="field" /> <pre > {{ meta }}</pre > </Field >
表单的提交
You will rarely need to access the form values inside the template, but it is there if you ever need it. What’s interesting is that vee-validate follows the assumption that most likely you will need the form values at the submission phase. 您很少需要在提交这一步骤之外使用表单值,基于这个假设,vee-validate只在提交阶段提供表单值。但如果您有需要,请额外使用v-model绑定你想要的元素
⬆️源自VeeValidate官方文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <script lang ="ts" setup > import { Form , Field , ErrorMessage } from 'vee-validate' ;const onSubmit = (values ) => { console .log (values); } const onInvalidSubmit =({values, errors, results} )=>{ console .log (values); console .log (errors); console .log (results); } const isRequired =(value:string )=> { if (value && value.trim ()) { return true ; } return '你没通过捏' ; } </script > <template > <Form @submit ="onSubmit" @invalid-submit ="onInvalidSubmit" > <Field name ="username1" :rules ="isRequired" #default ="{ field}" > <input v-bind ="field" type ="text" /> </Field > <Field name ="username2" :rules ="isRequired" #default ="{ errorMessage, field }" > <input v-bind ="field" type ="text" /> <p > {{ errorMessage }}</p > </Field > <button > 一个按钮</button > </Form > </template >
杂项 绑定初始值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <script lang ="ts" setup > ... const formValues ={ username1:'test1', username2:'test2', } </script > <template > <Form @submit ="onSubmit" :initialValues ="formValues" > <Field name ="username1" :rules ="isRequired" #default ="{ errorMessage, field}" > <input v-bind ="field" type ="text" /> <p > {{ errorMessage }}</p > </Field > <Field name ="username2" :rules ="isRequired" #default ="{ errorMessage, field }" > <input v-bind ="field" type ="text" /> <p > {{ errorMessage }}</p > </Field > <button > 1212</button > </Form > </template >
错误信息的显示 <*ErrorMessage* *name*="field" *as*="div" />
可以通过修改as的值,将错误信息改为自定义组件
更改值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <Form v-slot ="{ setFieldValue, setValues }" > <Field name ="email" /> <ErrorMessage name ="email" /> <Field name ="password" /> <ErrorMessage name ="password" /> <button type ="button" @click ="setFieldValue('email', 'test')" > Set Field Value</button > <button type ="button" @click ="setValues({ email: 'test', password: 'test12' })" > Set Multiple Values </button > </Form > <script lang ="ts" setup > ... const numval = ref(5) const myForm = ref() function changevalue(){ myForm.value.setFieldValue('username1',numval.value++) } function changevalues(){ myForm.value.setValues( { username1: 1, username2: 2 } ) } </script > <template > <Form @submit ="onSubmit" ref ="myForm" > <Field name ="username1" #default ="{ errorMessage, field}" > <input v-bind ="field" type ="number" /> <p > {{ errorMessage }}</p > </Field > <Field name ="username2" #default ="{ errorMessage, field }" > <input v-bind ="field" type ="number" /> <p > {{ errorMessage }}</p > </Field > <div @click ="changevalue" > 111</div > <div @click ="changevalues" > 222</div > </Form > </template >