由于 vue 的反应性模型, 您可以很容易地滚动自己的表单验证. 这可以通过对表单 submit 的一个简单方法调用来实现, 也可以通过计算属性来评估每次更改的输入数据.
然而, 使用表单验证很快就会变得麻烦, 尤其是当表单中的输入数量增加, 或者表单结构变得更加复杂时, 例如多步骤表单.
值得庆幸的是, Vue 有很多验证插件, 比如 Vuelidate. 在这篇文章中, 我们将看看 Vuelidate 如何被用来简化:
验证
多步骤的表单验证
子组件的验证
错误消息
我们还将看到如何使用 Vuelidate-error-extractor 插件简化每个输入的错误消息显示, 或者作为表单上下的错误摘要.
使用 Vuelidate 进行基本验证
Vuelidate 是面向数据模型的, 这意味着验证规则被添加到组件定义中的 validations 对象中, 而不是直接添加到 DOM 中的输入元素中.
结构必须类似于表单对象的结构, 但是验证规则的数量可以是动态的, 并根据需要验证的字段的不同而变化.
- export
- default {
- name:
- "FormComponent",
- data() {
- return {
- form: {
- name: "",
- email: ""
- }
- };
- },
- validations: {
- form: {
- name: {
- required
- },
- email: {
- required,
- }
- }
- }...
- };
这是一个实例:
定义自定义验证器
Vuetify 中的开箱即用验证规则适用于大多数情况, 但有时您需要一个定制的验证器.
使用 Vuelidate, 每个验证规则都是一个函数, 返回一个 Boolean 或 Promise 解析到一个 Boolean. 这意味着您可以在 validator .JS 文件中预先定义自己的验证器, 并在需要时导入每个验证器.
自定义验证器将当前验证的数据作为第一个参数接收, 将整个数据上下文作为第二个参数接收. 例如, 如果您有一个表单数据对象, 并且正在验证电子邮件属性, 那么第一个参数将是电子邮件本身, 第二个参数将是整个数据对象.
- // validators.JS
- export
- function isNameJoe(value) {
- if (!value) return true;
- return value === "Joe";
- }
- export
- function notGmail(value = "") {
- return ! value.includes("gmail");
- }
- export
- function isEmailAvailable(value) {
- if (value === "") return true;
- return new Promise((resolve, reject) =>{
- setTimeout(() =>{
- resolve(value.length> 10);
- },
- 500);
- });
- }
- // formComponent.vue
- import {
- required,
- }
- from "vuelidate/lib/validators";
- import {
- isNameJoe,
- notGmail,
- isEmailAvailable
- }
- from "@/validators";
- export
- default {
- name:
- "FormComponent",
- data() {
- return {
- form: {
- name: "",
- email: ""
- }
- };
- },
- validations: {
- form: {
- name: {
- required,
- isJoe: isNameJoe
- },
- email: {
- required,
- email,
- notGmail,
- isEmailAvailable
- }
- }
- },
- methods: {
- submit() {
- this.$v.form.$touch();
- // if its still pending or an error is returned do not submit
- if (this.$v.form.$pending || this.$v.form.$error) return;
- // to form submit after this
- alert("Form submitted");
- }
- }
- };
您还可以在一些带有 Vuelidate 的特殊帮助程序的帮助下创建自定义验证器. 查看 Vuelidate 文档中的 Custom Validators 部分以获得示例.
动态改变规则
能够动态更改验证规则对于多步骤表单来说是天赐之物. 每个步骤都有自己的规则来验证表单数据的某些部分.
Vuelidate 可以使用计算属性作为验证规则. 这意味着您可以为多步骤表单的每个步骤返回不同的规则.
在下面的示例中, 验证现在是一个返回对象的函数, 而不仅仅是一个对象. 这意味着在初始化组件并运行计算属性之后将调用它.
- export
- default {...data() {
- return {
- step:
- 1,
- maxSteps: 2,
- form: {
- name: "",
- email: ""
- }
- };
- },
- computed: {
- rules() {
- return this.step === 1 ? {
- name: {
- required
- }
- }: {
- email: {
- required,
- }
- }
- }
- },
- validations() {
- return {
- form: this.rules
- }
- }
- }
将大型表单分解为子组件
当表单变得更大时, 您可能希望将表单拆分为几个更小的组件, 以避免使用大型组件处理所有表单验证.
然而, 将表单数据存储在单独的组件而不是单个位置会使收集数据变得更加困难. 您可以通过 ref 绑定循环每个子组件并获取数据, 或者实现数据获取器方法, 或者以特定的方式命名表单数据.
另一种方法是将表单数据存储在 Vuex 中, 您可以在其中定义父项的所有规则, 并创建引用存储的表单状态的计算属性. 如果需要, 将验证器传递给每个组件.
提示: 如果将 Vuex 用于表单数据, 请尝试 Vuex -map-fields 插件, 通过将每个字段设置为计算属性来减少样板文件.
对于大多数情况, 我将所有数据和验证规则保存在父包装组件上, 该组件将相关验证器传递给每个子项作为 prop, 并处理将数据发送到服务器.
然后, 每个较小的组件在其验证器支柱上使用 $touch() 方法来注意数据正在被更改, 并通过 $emit('input', value) 发出更改后的数据, 以便于进行 v-model 绑定.
要使验证器对所有孩子可用, 您有几个选项:
将它作为一个支柱传递给每个组件
使用 Provide / Inject API
在商店中创建一个新的 Vue 实例. 检查这个可能有用的要点
这是第一种方法的实例, 即将向下传递给每个组件. 这是最容易理解的, 在大多数情况下将是您想要使用的那个.
https://codesandbox.io/s/nnxy0wjpwm?from-embed
一旦我们覆盖了错误消息显示, 我将向您展示使用 Provide / Inject API 的示例.
验证错误显示
表单已经就绪, 在每个按键上都进行了验证, 但是如何向用户显示错误消息呢?
我们可以检查每个验证器的错误并为我们的输入着色, 但是如果我们想要显示消息呢? 如果需要一次显示多个错误怎么办? 如果 / else 检查开始在各地飞来飞去.
- <div class="form-group" :class="{'hasError': v.$error }">
- <label class="mr-2 font-bold text-grey">Email</label>
- <input type="email" class="input" v-model="email" placeholder="user@yahoo.com" @input="v.$touch()">
- <div class="text-sm mt-2 text-red" v-if="v.$error">
- <div v-if="!v.required">Email is required</div>
- <div v-if="!v.notGmail">Email should not be a Gmail one</div>
- <div v-if="!v.isEmailAvailable">Email is not available (Less than 10 char)</div>
- <div v-if="!v.email">Email is not a properly formatted email address</div>
- </div></div>
正如您所看到的, 这里有很多重复, 很多检查, 您需要知道每个字段都有哪些验证器. 添加新规则意味着您也必须编辑模板.
使用 Vuelidate-error-extractor 显示错误
有一个更好的方法! 我编写的 Vuelidate-error-extractor 通过为每个字段提取所有错误, 为每个规则找到适当的错误消息并显示它, 为您完成了繁重的工作. 它为用户提供了一种灵活的方式, 以最小的样板文件和重复显示错误.
您可以使用 Bootstrap 和 Foundation 的内置模板之一, 也可以轻松构建我们自己的模板以满足您的需求. 您需要做的就是注册插件, 定义包含常见错误消息的对象并注册您要使用的模板. 我们将单输入错误显示称为 singleErrorExtractor.
创建自定义错误显示组件
Vuelidate-error-extractor 循环每个表单数据的验证, 并检查每个规则是否有效. 然后提取无效的错误, 并为它们分配验证错误消息.
绑定的 singleErrorExtractorMixin 提供了一组助手方法和计算属性, 以帮助开发人员构建自己的输入错误显示.
- <template>
- <div class="form-group" :class="{ hasError: hasErrors, hasSuccess: isValid }">
- <div class="label">{{ label }}</div>
- <div class="control">
- <slot/></div>
- <div class="control-helper text-red mt-4 text-sm" v-if="hasErrors">
- <div v-for="error in activeErrorMessages" :key="error">{{ error }}</div></div>
- </div>
- </template>
- <script>import {
- singleErrorExtractorMixin
- }
- from "vuelidate-error-extractor";
- export
- default {
- mixins:
- [singleErrorExtractorMixin]
- };</script>
现在只需使用新组件包装您的输入:
- <form @submit.prevent="handleForm">
- <form-group :validator="v" label="Email">
- <input
- class="input"
- type="email"
- v-model="email"
- placeholder="user@yahoo.com"
- @input="v.$touch()"
- >
- </form-group></form>
查看自定义模板文档, 以获取有关如何进行自己的错误显示的详细说明.
如此灵活意味着您可以将其适应您希望的任何 Vue UI 框架. 以下是一个流行的 UI 框架列表以及如何为每个框架实现它的示例: https://dobromir-hristov.github.io/vuelidate-error-extractor/other_frameworks.html
表单错误摘要
有时您需要对表单中的所有错误进行汇总, 无论是在顶部还是底部.
您可以使用 Foundation 或 Bootstrap 的预构建组件, 使用 baseMultiErrorExtractor 组件或 multiErrorExtractormixin. 对于 90%的用例, 这样 baseMultiErrorExtractor 就足够了.
- <template>
- <base-errors v-bind="$attrs">
- <div class="text-red" slot-scope="{ errorMessage }">{{ errorMessage }}</div></base-errors>
- </template>
- <script>import {
- templates
- }
- from "vuelidate-error-extractor";
- export
- default {
- inheritAttrs:
- false,
- components: {
- baseErrors: templates.multiErrorExtractor.baseMultiErrorExtractor
- }
- };</script>
它将重用您为 singleerrorex 拖拉机预先定义的相同错误消息. 必须将 $validator 作为一个道具传递.
为了能够为每个错误分配适当的字段标签, 它需要 attributes 定义一个被定义的对象, 其中定义了错误消息. 此对象表示一个地图, 用于标注应如何调用每个字段, 即 { name: "Name", email: "Email" }.
通过注入验证器来减少样板
传递 validator 和 attribute 支持每个表单输入和 multiErrorExtractor 可能会很快烦人, 更不用说样板.
要解决此问题, 您可以使用提供的 form-wrapper 组件将验证器注入所有输入.
- <template>
- <div class="form pt-6">
- <form-wrapper :validator="$v.form">
- <form-summary/>
- <form @submit.prevent="submit" novalidate>
- <div class="flex text-center my-6 text-left">
- <div class="w-1/2">
- <name-component v-model="form.name"/>
- </div>
- <div class="w-1/2">
- <email-component v-model="form.email"/>
- </div>
- </div>
- <div class="text-center">
- <button type="submit" class="button">
- Submit </button>
- </div>
- </form>
- </form-wrapper>
- </div></template>
该方法使用 Provide/Inject API 将 $validator 传递给需要它的所有组件. 然后, 每个表单组可以删除它的验证器和属性道具, 由一个名称道具替换, 并在它所代表的表单中标注哪个字段.
它还将尝试通过检查前面定义的 attributes 对象来确定输入的 attribute 属性.
摘要
正如您所见, 在前端处理和验证表格往往会成为一种痛苦, 特别是当表格变大并且需要拆分时.
使用 Vuelidate 使整个考验变得更加可忍受. 与 Vuelidate-error-extractor 配合使用, 在每个输入下显示错误消息可以从繁琐的重复性工作, 到简单地添加一个或多个包装组件, 为您完成所有操作.
来源: http://www.css88.com/web/vue-js/11837.html