Vue.js中的表单验证

哈Ha!

表单验证是网站上最重要的任务之一。 我们必须验证数据是否存在,匹配模式,创建异步验证,仅在从字段中移出焦点之后或提交表单之前应用验证...有时,这对于开发人员来说是真正的麻烦。

Vue.js包含许多有趣且不寻常的验证方法,可帮助解决您的问题。 概述下切!


TL; DR


使用Vuelidate

常见错误


HTML5验证


HTML5使开发人员能够使用新的字段属性和Validation API来验证表单。 我们可以直接在vue模板中使用它们。

例如,这里是一个简单的注册表格,由三个字段组成:电子邮件字段,密码字段和密码重播字段。 对于前两个,我们使用使用属性进行验证,对于前三个,使用属性和Validation API:

<template> <form @submit.prevent="someAction()"> <input v-model="email" type="email" required> <input v-model="password" type="password" required> <input v-model="repeatedPassword" type="password" required ref="repeatedPasswordEl"> <button type="submit">   </button> </form> </template> <script> export default { data() { return { email: null, password: null, repeatedPassword: null, }; }, watch: { repeatedPassword: 'checkPasswordsEquality', password: 'checkPasswordsEquality', }, methods: { checkPasswordsEquality() { const { password, repeatedPassword } = this; const { repeatedPasswordEl } = this.$refs; if (password !== repeatedPassword) { repeatedPasswordEl.setCustomValidity( '  ', ); } else { repeatedPasswordEl.setCustomValidity(''); } }, }, }; </script> 

沙盒示例

即使在这样一个简单的示例中,您也会看到许多问题:

  • 浏览器一次只显示一个错误。 用户将不得不尝试多次提交表单以查看其所有错误。
  • 仅在尝试提交表单后,错误才会显示给用户。 要更改此行为,您将不得不编写另一吨代码:在blur事件的每个元素上调用reportValidity()函数。
  • 对于样式化输入字段,只有伪类:有效和:无效,当输入字段中的数据不正确但用户尚未与之交互时,无法捕获状态。
  • 每种浏览器都以自己的方式显示验证错误,它们在您的设计中可能很难看。
  • Vue.js中的验证API使用起来很不方便:您必须将元素保存在$ refs中。

如果项目中只有一个表单,并且仅由您使用,那么HTML5验证是一个很好的选择。 在所有其他情况下,请尝试使用其他方法。

图书馆验证


我在项目中遇到的另一个常见问题是库验证。

 <template> <form @submit.prevent="someAction()"> <input v-model="email" type="email" @blur="isEmailTouched = true" :class="{ error: isEmailError }" > <div v-if="isEmailError">    </div> <button :disabled="!isEmailValid" type="submit">   </button> </form> </template> <script> const emailCheckRegex = /^... RegExp   Email...$/; export default { data() { return { email: null, isEmailTouched: false, }; }, computed: { isEmailValid() { return emailCheckRegex.test(this.email); }, isEmailError() { return !this.isEmailValid && this.isEmailTouched; }, }, }; </script> 

沙盒示例

这种方法没有问题。 除了在具有多个字段的表单中,会产生很多重复的代码,并且每个开发人员都以自己的方式编写验证。

解决所有问题的最佳方法是使用社区提供给我们的库。 当前有两种流行的表单验证解决方案:


每种方法都有其独特的方法,我们将在下面详细介绍。

验证


vee-validate-在第一个Vue.js版本期间出现的用于验证的库,具有很大的社区,并用于大量项目中。

年龄会影响体重-31 KB(最小化+ GZIP),是Vue.js本身的一半半! 这是由于该库立即包含一堆东西:

  • 35个内置验证器
  • 错误的英文翻译
  • 验证指令
  • 验证组件

该库支持41种语言的错误。 要以所需的本地化安装和使用它,只需执行几个步骤:

 npm i vee-validate 

 /* main.js */ import Vue from 'vue'; import VeeValidate, { Validator } from 'vee-validate'; import ru from 'vee-validate/dist/locale/ru'; Validator.localize('ru', ru); Vue.use(VeeValidate, { locale: 'ru', }); /* ... */ 

Vee验证有两种验证方法:使用指令和使用组件。

使用v-validate指令进行验证


使用伪指令的方法非常简单:将v-validate伪指令放在输入字段中,并向其传递验证器列表。 然后可以从组件内部的字段字段和错误中获取验证状态和错误行。

以它的使用为例,让我们做一个简单的表格:

-包含“系列和护照号码”字段
-包含“护照签发日期”字段
-包含“名称”字段
-如果数据不正确,将禁用的属性添加到表单的提交按钮

 <template> <form @submit.prevent="someAction()"> <div> <!--             data-vv-as -          name -      --> <input type="text" v-model="passportData" v-validate="{ required: true, regex: /^\d{4} \d{6}$/ }" data-vv-as="   " name="passport_data" > <span v-if="errors.has('passport_data')"> {{ errors.first('passport_data') }} </span> </div> <div> <!--           .      v-model- lazy     fields.passport_date  invalid  ,       touched ,      blur --> <input type="text" v-model.lazy="passportDate" v-validate="{ required: true, date_format: 'dd.MM.yyyy' }" data-vv-as="  " name="passport_date" > <span v-if="fields.passport_date && fields.passport_date.touched && fields.passport_date.invalid" > {{ errors.first('passport_date') }} </span> </div> <div> <!--       ,    continues   errors.collect() --> <input type="text" v-model="name" v-validate.continues="{ required: true, alpha: true, max: 10 }" data-vv-as="" name="name" > <span v-for="error in errors.collect('name')" :key="error" > {{ error }} </span> </div> <button type="submit" :disabled="!isFormValid" >   </button> </form> </template> <script> export default { data() { return { passportData: null, name: null, passportDate: null, }; }, computed: { // ,      isFormValid () { return Object.keys(this.fields).every(field => this.fields[field].valid); }, }, }; </script> 

沙盒示例

如您所见,当在fields.passport_date中使用标志时,我不得不检查passport_date字段是否存在-在第一次渲染期间,vee-validate没有有关您的字段的信息,因此,没有带有标志的对象。 要摆脱此检查,请使用特殊的mapFields帮助器。

组件验证


去年年底出现的新验证方法是使用组件。 作者自己建议使用这种方法,它与Vue.js@2.6中的新插槽语法非常吻合。

该库提供两个组件:

  • ValidationProvider-在其中描述验证并在其中包裹输入字段的组件。
  • ValidationObserver-组合多个ValidationProvider的验证标志的组件。

这是过去示例的形式,但使用组件编写:

 <template> <!-- ValidationObserver      .      valid      --> <ValidationObserver v-slot="{ valid }"> <form @submit.prevent="doAction()"> <!-- ValidationProvider                 name - ,      --> <ValidationProvider name="   " :rules="{ required: true, regex: /^\d{4} \d{6}$/ }" v-slot="{ errors }" > <input type="text" v-model="passportData"> <span v-if="errors[0]"> {{ errors[0] }} </span> </ValidationProvider> <!--         input,    blur  change  mode="lazy"  mode="eager" --> <ValidationProvider name="  " :rules="{ required: true, date_format: 'dd.MM.yyyy' }" v-slot="{ errors }" mode="lazy" > <input type="text" v-model="passportDate"> <span v-if="errors[0]"> {{ errors[0] }} </span> </ValidationProvider> <!--       ,     :bails="false" --> <ValidationProvider name="" :rules="{ required: true, alpha: true, max: 10 }" v-slot="{ errors }" :bails="false" > <input type="text" v-model="name"> <span v-for="error in errors" :key="error" > {{ error }} </span> </ValidationProvider> <button type="submit" :disabled="!valid">   </button> </form> </ValidationObserver> </template> <script> import { ValidationProvider, ValidationObserver } from 'vee-validate'; export default { components: { ValidationProvider, ValidationObserver, }, data() { return { passportData: null, passportDate: null, name: null, }; }, }; </script> 

沙盒示例

其他图书馆功能



问题所在


当然, 第一个也是最大的问题是它的大小。 该库不支持摇树和有选择地添加验证器。 不管您是否喜欢,您的帮派将始终具有2个组成部分和一个验证指令,一个英语翻译版本和35个验证程序。

第二个问题是由于基于事件的订阅方法,与其他库集成时也会出现问题,这些库也会更改输入字段(屏蔽程序等)的行为。

第三个问题-一个比较主观的问题-错误的翻译是普遍和丑陋的,没有反映出真正的本质。

采取过去例子的形式。 如果输入错误的护照号码和日期,您将收到以下错误:

        .         dd.MM.yyyy. 

我想用更易读的内容代替它们:

          1234 567890         .. 

絮状


Vuelidate库的出现是为了响应vee-validate库所包含方法的问题。 Vuelidate既没有字段的事件处理程序,也没有验证错误的转换。

它只需要做一件事-在验证对象中描述验证。 然后她自己将创建一个具有字段验证标志和用于更改这些标志的函数的计算字段$ v。

由于其简单的验证方法,Vuelidate的重量仅为3.4 KB(最小化+ GZIP),几乎是vee-validate的10倍。

它的安装同样容易:

 npm i vuelidate 

 /* main.js */ import Vue from 'vue' import Vuelidate from 'vuelidate' Vue.use(Vuelidate) /* ... */ 

使用Vuelidate重写上一个示例中的表单:

 <template> <form @submit.prevent="someAction()"> <!--      ,  $v.passportData.$invalid   ,     --> <div> <input type="text" v-model="passportData"> <span v-if="$v.passportData.$invalid">         1234 567890 </span> </div> <!--      blur  $touch()   $v.passportDate.$dirty  true.  $v.passportDate.$error   $v.passportDate.$invalid && $v.passportDate.$dirty --> <div> <input type="text" v-model="passportDate" @blur="$v.passportDate.$touch()"> <span v-if="$v.passportDate.$error">      .. </span> </div> <!-- ,       blur,     $v.passportDate.$model - ,     : - Vuelidate     passportDate - Vuelidate   $touch()   $v.passportDate  lazy ,      blur --> <div> <input type="text" v-model.lazy="$v.passportDate.$model"> <span v-if="$v.passportDate.$error">      .. </span> </div> <!--     --> <div> <input type="text" v-model="name" @blur="$v.name.$touch()"> <span v-if="$v.name.$error"> <template v-if="!$v.name.maxLength">      {{ $v.name.$params.maxLength.max }}  </template> <template v-else-if="!$v.name.alpha">      </template> <template v-else>     </template> </span> </div> <button type="submit" :disabled="$v.$invalid">   </button> </form> </template> <script> import { required, maxLength } from 'vuelidate/lib/validators'; import moment from 'moment'; export default { data() { return { passportData: null, name: null, passportDate: null, }; }, //   ,  Vuelidate   computed- $v validations: { //        data passportData: { required, validFormat: val => /^\d{4} \d{6}$/.test(val), }, passportDate: { required, validDate: val => moment(val, 'DD.MM.YYYY', true).isValid(), }, name: { required, maxLength: maxLength(10), alpha: val => /^[-]*$/i.test(val), }, }, }; </script> 

沙盒示例

使用功能可以快速轻松地描述自定义验证器。 如果希望验证器参数属于$ params对象,请使用特殊的withParams帮助器。

如您所见,具有多个错误的字段会占用大量空间并且看起来很怪异-这是通过创建一个单独的用于显示验证的组件来解决的。

其他图书馆功能



问题所在


在这些问题中,一个人可以开箱即用地挑选出数量相对较少的验证器;通常,您必须编写自己的函数进行验证。

结论


我在许多项目中使用了Vuelidate库,但从未遇到无法解决的问题。 对我来说,她仍然是最佳选择。 如果您关心代码的大小,并且更喜欢使用模型方法来描述验证,那么采用它,简单的文档和丰富的api可以验证任何复杂的形式。

如果您要在内部使用管理面板,则不想在错误行上花费一小段时间-选择vee-validate。 这将有助于快速且没有问题地编写许多验证。

感谢您的关注!

Source: https://habr.com/ru/post/zh-CN444900/


All Articles