表单验证以难以实现而闻名。在本教程中,我们将把一部分内容分解开来研究,以降低这个问题的难度。为表单创建良好的抽象是Vue.js擅长的事情,而Vuelidate是我个人最喜欢的表单验证工具,因为它使用起来很简单。另外,它非常灵活,所以我们甚至不需要考虑要怎么使用它。我在这里先抛出一个观点。
如果你只是想复制粘贴我的完整的工作示例,它在文章最后。去做吧。我不会说什么。这样你花的时间肯定不会超过一小时,而是两分钟?!啊,互联网真是一个美丽的地方。
你可能会发现你需要修改我们在本文中使用的表单,在这种情况下,你可以阅读完整的内容。我们将从一个简单的例子开始,并逐步构建出一个更具体的例子。最后,我们将讨论如何在用户完成表单后显示表单错误。
#最简单的情况: 完成输入后显示输入内容
首先,我们来展示一下如何使用Vuelidate。我们需要创建一个名为validations的对象,它将反映我们试图从表单中捕获的数据结构。用最简单的术语来说,它应该是这样的:
这将在计算属性中创建一个对象,我们可以用$v找到这个对象。在Vue DevTools中看起来是这样的:
这里需要注意几件事: $v是一个计算属性。这很好,因为这意味着它会一直缓存到有更新为止,这是处理这些状态更改的一种非常有效的方式。如果你想了解更多关于这个概念的背景知识,请阅读我的文章。
另外需要注意的是: 这里有两个对象—一个是关于所有验证的通用对象(目前这里只有一个),另一个是关于特定属性name的对象。这很好,因为如果我们要查找所有字段的全部信息,我们就会得到这些信息。而我们需要收集特定的数据,我们也会得到。
我们来看看当我们在输入框输入内容时发生了什么:
从得到的data中我们可以看出……好吧,我打字像个疯子。但是我们来看看其他的一些字段。在本例中,$dirty指的是表单是否被touched(访问)过。我们还可以看到,$model字段现在被填入了name对象,它显示了data中的内容。
$error和$invalid听起来是一样的,但实际上有一点不同。$invalid检查内容是否通过验证,但是$error同时检查$invalid内容和是否是$dirty(表单是否被touched(访问))。这一切是否看起来都需要进行大量的解析(哈哈,明白了吗?解析?),别担心,我们将一步一步地分析其中的许多部分。
#安装Vuelidate并创建我们的第一个表单验证
这是一个很简单的例子。我们来实际创建一下它。我们将把这个例子引入到我们的应用程序中,这次我们将字段设置为必填项,并给它一个最小长度要求。在Vue应用中,我们将首先添加Vuelidate:
现在,我们来进入main.js文件并对它更新如下:
现在,在任何包含表单元素的组件中,我们首先导入我们所需要的验证器:
然后,我们将数据放入一个函数中,以便我们可以重用组件。你可能知道这一点。接下来,我们将name表单字段放在一个对象中,因为通常来说,我们希望将所有表单数据一起捕获。
我们还需要将验证包含进来,它将反映我们的数据。我们将再次使用required关键字,但这次我们还将为字符的最小长度添加一个键/值对,即minLength(x),它看起来像这样:
接下来,考虑到易访问性,我们将在模板中创建一个标签。我们将使用前面在validations对象中看到的计算属性($model)来在v-model中创建关联,代替使用数据中的内容。
最后,我们将在位于输入框下方的表单下方放置一些文本。我们可以使用required附加到formResponse.name来看看它的评估是否正确,以及是否提供了这个功能。我们还可以看看字符的长度是否大于最小值。我们甚至会得到一个params对象,它将告诉我们指定的字符数。我们将使用所有这些为用户创建信息丰富的错误消息。
我们还将样式化错误类,这样就能一目了然地看到它们就是错误。
#偷个懒
在上一个演示中,你可能已经注意到错误会立即出现,并在键入时进行更新。就我个人而言,我不喜欢以那种方式显示表单验证,因为我认为这会分散注意力且容易混淆。我喜欢做的是等到输入完成后再进行评估。对于这种交互,Vue为v-model:v-model.lazy提供了一个修饰器。它只会在用户完成输入任务后计算双向绑定。
我们现在可以像这样来改进我们的单个表单输入:
#创建自定义验证器
Vuelidate自带了很多验证器,都非常有用。然而,有时我们需要更多的自定义。我们来为一个强密码定制一个验证器,并检查它是否与Vuelidate的sameAs验证器相符合。
我们要做的第一件事是在输入框上添加一个标签,输入框类型是type="password"。
在我们的数据中,我们将在formResponses对象中创建password1和password2(稍后我们将使用它们来验证匹配的密码),并从验证器中导入我们需要的内容。
然后,我们将创建我们的自定义验证器。在下面的代码中,你可以看到我们使用正则表达式进行不同类型的验证。我们将创建一个strongPassword方法,传入我们创建的password1,然后我们可以用.test()以几种方式来检查它。.test()的工作原理与你所预期的一样: 如果传递参数,则必须传递true;如果不传递,则必须传递false。
我把每一行都分开,这样你就能看到发生了什么,但是我们也可以把整个内容写成这样的一行:
我更喜欢把它拆开,因为那样更容易修改。
这也允许我们为验证结果生成错误文本。我们可以把错误文本修改成我们喜欢的任何东西,甚至可以把它从一个v-if中提取出来并显示在页面上。这由你决定!
现在我们可以用Vuelidate的sameAs方法来检查第二个密码和第一个密码是否匹配:
现在,我们可以创建第二个密码字段:
现在你可以看到整个部分都在一起运行:
#对完成情况进行评估
在完成表单之前,你可以看到上一个示例是多么嘈杂。在我看来,更好的途径是评估整个表单何时完成,这样用户就不会在输入表单的过程中被打断。我们可以这样做。
还记得我们什么时候查看了$v包含的计算属性吗?它有用于所有单个属性的对象,也有用于所有验证的对象。它的内部还有三个非常重要的值:
$anyDirty: 表单是否被touched(访问)或留空
$invalid: 表单中是否有任何错误
$anyError: 是否有任何错误(即使只有一个),那么它的值将为true
你可以使用$invalid,但我更喜欢$anyError,因为它不需要我们检查表单是否是dirty(不真实的)。
我们来改进一下上一个表单。我们将加入一个submit按钮和一个uiState字符串来跟踪UI状态!这非常有用,因为我们可以跟踪我们是否尝试过提交,以及我们是否准备好发送收集到的内容。我们还对样式做了一个小的改进: 将错误定位在表单上,这样表单就不会为了显示错误而来回移动。
首先,我们来添加一些新的数据属性:
现在,我们将在表单的末尾添加一个submit按钮。@click指令末尾的.prevent修饰符的作用类似于preventDefault,可以防止页面重载:
我们将在submitForm方法中处理一些不同的状态。我们将使用Vuelidate($anyDirty)中的计算属性来查看表单是否为空。记住,我们可以从this.$v这里收集信息。我们使用formResponses对象来保存所有的表单响应,所以我们要使用的是this.$v.formResponses.$anyDirty。我们将该值映射到我们的“空”数据属性。我们也会对错误进行同样的处理,并且我们会将uiState更改为“submitclicked”:
如果表单没有错误且不为空,我们将发送响应并将uiState更改为“form committed”。
现在,我们还可以处理一些错误状态和空状态,最后,如果表单被提交,我们将评估是否成功。
在这个表单中,我们给出了每个部分的相对定位,并在底部添加了一些填充。这将允许我们对错误状态进行绝对定位,从而防止表单四处移动。
我们需要做的最后一件事是: 既然我们已经将错误完全放在表单中了,那么它们就会叠在一起,除非我们将它们一个挨着一个放在一起。我们还想检查表单是否处于错误状态中,这只有在单击submit按钮后才会为真。这是一种非常有用的方法——在用户完成表单操作之前,我们不会显示错误,因为这样做的入侵性更小。这取决于你是想这样做还是想按照前几节中使用的v-model.lazy示例来做。
我们之前的错误看起来是这样的:
现在,我们像这样把它们包含在一起:
为了让你更轻松地处理这些错误,有一个库可以根据你的验证动态来计算出要显示哪些错误。超级酷!如果你在做一些简单的事情,使用它可能会带来太多的开销,但是如果你有一个非常复杂的表单,它可能会节省你的时间:)
至此,我们已经完成了表单验证部分的设计! 我们也对我们的表单进行了验证,当需要时,会显示错误和空状态,但当我们输入时什么都不会显示。
衷心感谢Vuelidate的维护者之一Damian Dulisz对本文的验证。
英文原文:https://css-tricks.com/form-validation-in-under-an-hour-with-vuelidate/ 译者:天天向上