如何在 Vue.js 中验证表单

介绍

Form validation,也称为表单字段验证,确保用户在网页表格中填写所有所需的字段. 如果一个字段具有无效的值,则会显示错误消息,并防止表单提交,直到值满足所有规则。

模板驱动验证是一种表单验证类型,其中使用指令直接在表单元件中设置验证规则。

要在 Vue.js 中实施模板驱动的验证,我们可以使用 VeeValidate

以下是您将在本教程中建立的动画图像:

Animated gif of form validation with VeeValidate

在本教程结束时,您将有一个注册表格,它使用VeeValidate来验证输入字段。

前提条件

本教程假定您对 JavaScript 字符串和对象有了解,对 Vue 的了解有益,但不需要。 要了解更多关于 Javascript 的信息,请参阅 How To Code in Javascript系列。

我们将专注于构建一个单一的本地HTML文件,引用各种云托管库. 可以使用@vue/cli创建Vue项目,并使用包管理器安装vee-validate;然而,这种方法不在本教程的范围内。

步骤 1 — 使用 VeeValidate 设置 Vue.js 项目

您需要 Vue.js 框架和 VeeValidate 库。

首先,使用您的终端创建一个名为register.html的新文件:

1nano register.html

并为网页添加一些初始代码:

 1[label register.html]
 2<html>
 3<head>
 4  <meta charset="utf-8">
 5  <meta name="viewport" content="width=device-width,initial-scale=1.0">
 6  <title>Vue Template Form Validation</title>
 7</head>
 8<body>
 9
10  <!-- ... -->
11
12</body>
13</html>

Vue.js 的浏览器构建可通过cdnjs提供。VeeValidate 的浏览器构建可通过jsdelivr提供。

 1[label register.html]
 2<body>
 3
 4  <!-- include the Vue.js framework -->
 5  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
 6
 7  <!-- include the VeeValidate library -->
 8  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vee-validate.min.js"></script>
 9
10</body>

这些文件由CDN(内容交付网络)提供,无需本地下载或保存。

您现在有一个网页,可以使用 Vue.js 和 VeeValidate 的最新稳定版本。

添加 Bootstrap 和 Awesome 字体

要建立一些风格,你可以使用 Bootstrap,要添加一些图形,你也可以使用 Font Awesome

Bootstrap 和 Font Awesome 的浏览器构建可通过 BootstrapCDN. 添加到 register.html 文件的 <head>:

 1[label register.html]
 2<head>
 3  <meta charset="utf-8">
 4  <meta name="viewport" content="width=device-width,initial-scale=1.0">
 5  <title>Vue Template Form Validation</title>
 6
 7  <!-- include the Bootsrap framework -->
 8  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
 9
10  <!-- include Font Awesome -->
11  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
12</head>

此时,您有Vue、VeeValidate、Bootstrap 和Awesome 字体,接下来,您将创建验证的表单。

构建形状标记

此示例表格将从用户那里寻找五个信息,您将需要一个名称,电子邮件,用户名,密码密码_确认

首先,在<script>标签之前,在register.html文件的<body>中添加一些表单的初始标记:

 1[label register.html]
 2<body>
 3  <div class="container my-3">
 4    <div class="row justify-content-around">
 5      <div class="col-6 rounded shadow">
 6        <h1 class="py-3">Sign up once and watch any of our free demos.</h1>
 7        <div id="signup-form">
 8          <form>
 9
10          <!-- ... form fields ... -->
11
12          </form>
13        </div>
14      </div>
15    </div>
16  </div>
17
18  <!-- ... library script tags ... -->
19</body>

此代码建立一个空的<form>,并使用一些Bootstrap实用程序来布局和外观。

接下来,将表单字段添加到 <form>. 以 name 的字段开始:

 1[label register.html]
 2<form>
 3
 4  <div class="form-group">
 5    <label for="name">Your Name</label>
 6    <div class="input-group">
 7      <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-user" aria-hidden="true"></i></span></span>
 8      <input type="text" id="name" name="name" placeholder="Name" class="form-control" />
 9    </div>
10  </div>
11
12</form>

此代码为名称创建一个<label>,为fa-user创建一个Awesome字体图标,为name创建一个<input>

您可以对其他信息(如电子邮件,用户名,密码密码_确认)进行类似的添加:

 1[label register.html]
 2<form>
 3
 4  <!-- ... name ... -->
 5
 6  <div class="form-group">
 7    <label for="email">Your Email</label>
 8    <div class="input-group">
 9      <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-envelope" aria-hidden="true"></i></span></span>
10      <input type="email" id="email" name="email" placeholder="[email protected]" class="form-control" />
11    </div>
12  </div>
13
14  <div class="form-group">
15    <label for="username">Username</label>
16    <div class="input-group">
17      <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-users" aria-hidden="true"></i></span></span>
18      <input type="text" id="username" name="username" placeholder="Enter your username" class="form-control" />
19    </div>
20  </div>
21
22  <div class="form-group">
23    <label for="password">Password</label>
24    <div class="input-group">
25      <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span>
26      <input type="password" id="password" name="password" placeholder="Enter a password" class="form-control" />
27    </div>
28  </div>
29
30  <div class="form-group">
31    <label for="password_confirmation">Confirm Password</label>
32    <div class="input-group">
33      <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span>
34      <input type="password" id="password_confirmation" name="password_confirmation" placeholder="Re-type password" class="form-control" />
35    </div>
36  </div>
37
38</form>

此代码创建了<label>、一个字体 Awesome 图标和<input> 每个输入都具有独特的idname

添加一个注册按钮来填写<表格>:

 1[label register.html]
 2<form>
 3
 4  <!-- ... form fields ... -->
 5
 6  <div class="form-group">
 7    <button type="submit" class="btn btn-block btn-lg btn-primary">Register</button>
 8  </div>
 9
10</form>

此代码使用 Bootstrap 样式创建一个大型提交按钮。

您可以在网页浏览器中打开register.html,查看应用程序的进展。

步骤 2 — 创建和安装 Vue 实例

接下来,您将创建一个Vue实例,并将其安装在#signup-form中。

添加一个新的<script>标签在<body>的末尾,并定义signupForm:

 1[label register.html]
 2<body>
 3  <!-- ... form ... -->
 4  <!-- ... library script tags ... -->
 5
 6  <script>
 7    const signupForm = new Vue({
 8      el: '#signup-form'
 9    });
10  </script>
11</body>

数据对象添加属性:

 1[label register.html]
 2<body>
 3  <!-- ... form ... -->
 4  <!-- ... library script tags ... -->
 5
 6  <script>
 7    const signupForm = new Vue({
 8      el: '#signup-form',
 9      data: {
10        name: '',
11        email: '',
12        username: '',
13        password: '',
14        password_confirmation: ''
15      }
16    });
17  </script>
18</body>

然后,在每个字段中引用v模型的属性。

对于名称字段,添加以下内容:

1[label register.html]
2<input type="text" id="name" name="name" placeholder="Name" class="form-control" v-model="name" />

对于电子邮件字段,添加以下内容:

1[label register.html]
2<input type="email" id="email" name="email" placeholder="[email protected]" class="form-control" v-model="email" />

对于用户名字段,添加以下内容:

1[label register.html]
2<input type="text" id="username" name="username" placeholder="Enter your username" class="form-control" v-model="username" />

对于密码字段,添加以下内容:

1[label register.html]
2<input type="password" id="password" name="password" placeholder="Enter a password" class="form-control" v-model="password" />

最后,对于password_confirmation字段,添加以下内容:

1[label register.html]
2<input type="password" id="password_confirmation" name="password_confirmation" placeholder="Re-type password" class="form-control" v-model="password_confirmation" />

在此时刻,您有一个Vue实例,包含名称,电子邮件,用户名,密码密码_确认的模型。

步骤 3 – 添加验证观察员验证提供者

接下来,您需要注册验证观察员验证提供者

您可以将两者添加到新的<script>标签,然后在<body>的末尾:

 1[label register.html]
 2<body>
 3  <!-- ... form ... -->
 4  <!-- ... library script tags ... -->
 5
 6  <script>
 7    Vue.component('validation-observer', VeeValidate.ValidationObserver);
 8
 9    Vue.component('validation-provider', VeeValidate.ValidationProvider);
10  </script>
11
12  <!-- ... vue instance script tag ... -->
13</body>

现在,您可以使用<validation-observer>包装整个<form>并使用<validation-provider>包装这些字段:

 1[label register.html]
 2<validation-observer>
 3
 4  <form>
 5
 6    <div class="form-group">
 7      <validation-provider>
 8        <label for="name">Your Name</label>
 9        <div class="input-group">
10          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-user" aria-hidden="true"></i></span></span>
11          <input type="text" id="name" name="name" placeholder="Name" class="form-control" v-model="name" />
12        </div>
13      </validation-provider>
14    </div>
15
16    <div class="form-group">
17      <validation-provider>
18        <label for="email">Your Email</label>
19        <div class="input-group">
20          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-envelope" aria-hidden="true"></i></span></span>
21          <input type="email" id="email" name="email" placeholder="[email protected]" class="form-control" v-model="email" />
22        </div>
23      </validation-provider>
24    </div>
25
26    <div class="form-group">
27      <validation-provider>
28        <label for="username">Username</label>
29        <div class="input-group">
30          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-users" aria-hidden="true"></i></span></span>
31          <input type="text" id="username" name="username" placeholder="Enter your username" class="form-control" v-model="username" />
32        </div>
33      </validation-provider>
34    </div>
35
36    <div class="form-group">
37      <validation-provider>
38        <label for="password">Password</label>
39        <div class="input-group">
40          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span>
41          <input type="password" id="password" name="password" placeholder="Enter a password" class="form-control" v-model="password" />
42        </div>
43      </validation-provider>
44    </div>
45
46    <div class="form-group">
47      <validation-provider>
48        <label for="password_confirmation">Confirm Password</label>
49        <div class="input-group">
50          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span>
51          <input type="password" id="password_confirmation" name="password_confirmation" placeholder="Re-type password" class="form-control" v-model="password_confirmation" />
52        </div>
53      </validation-provider>
54    </div>
55
56    <div class="form-group">
57      <button type="submit" class="btn btn-block btn-lg btn-primary">Register</button>
58    </div>
59
60  </form>
61
62</validation-observer>

您现在已经准备了一个表格,包含了验证观察员验证提供者

步骤4 – 使用VeeValidate规则

VeeValidate 规则会对可以在一个或多个字段中输入的内容设置限制或条件。当您更新包含需要验证的字段的记录时,会检查验证规则。

例如,您可以使用必要验证器:

1<validation-provider rules="required">

您可以通过通过一个管道字符(``)分开的多个验证。

例如,您可以使用必需电子邮件验证器:

1<validation-provider rules="required|email">

或者,您可以通过一个对象以获得更大的灵活性:

1<validation-provider :rules="{ required: true, email: true, regex: /[0-9]+/ }">

现在,每次输入更改时,验证器将从左到右运行验证列表,每次输入失败时填充错误辅助对象。

正如在撰写本教程时,VeeValidate 有 30 个表单验证规则 具有创建自己的规则的选项。

适用规则

接下来,您需要导入VeeValidateRules

您可以将其添加到新的<script>标签,然后在register.html文件中的<body>的末尾:

1[label register.html]
2<body>
3  <!-- ... form ... -->
4  <!-- ... library script tags ... -->
5
6  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/rules.umd.js"></script>
7
8  <!-- ... vue instance tags ... -->
9</body>

然后,您可以绕过规则,使它们都可用:

 1[label register.html]
 2<body>
 3  <!-- ... form ... -->
 4  <!-- ... library script tags ... -->
 5
 6  <script>
 7    Object.keys(VeeValidateRules).forEach(rule => {
 8      VeeValidate.extend(rule, VeeValidateRules[rule]);
 9    });
10  </script>
11
12  <!-- ... vue instance tags ... -->
13</body>

并适用于所有输入的必要规则:

1[label register.html]
2<validation-provider rules="required">

适用多种规则

对于电子邮件,您还将适用于有效电子邮件地址的规则:

1[label register.html]
2<validation-provider rules="required|email">

对于密码,您还将适用于最低长度为6字符的规则:

1[label register.html]
2<validation-provider rules="required|min:6">

现在,您对这些字段有要求电子邮件我的规则。

应用跨领域验证

对于password_confirmation,您需要匹配password的值才能有效,而要做到这一点,您将依赖ValidationObserver,允许password_confirmation知道password

密码字段中添加vid,因此password_confirmed有一个目标:

1[label register.html]
2<validation-provider rules="required|min:6" vid="password">

确认规则添加到password_confirmation字段中,因此password_confirmed将其值与password的值进行比较:

1[label register.html]
2<validation-provider rules="required|confirmed:password">

现在,您已为这些字段设置了要求电子邮件我的确认规则。

添加定制规则

VeeValidate 允许您用扩展验证来编写自定义验证规则和消息。

在此示例中,您将限制用户使用admin,passwordadministrator这些单词:

 1[label register.html]
 2<body>
 3  <!-- ... form ... -->
 4  <!-- ... library script tags ... -->
 5
 6  <script>
 7    // Declare an array of usernames that are invalid.
 8    const restricted_usernames = [
 9      'admin',
10      'password',
11      'administrator'
12    ];
13
14    // Extend the custom rule.
15    VeeValidate.extend('checkuser', {
16      name: 'Restricted Usernames',
17      validate: value => {
18        return restricted_usernames.includes(value.toLowerCase()) ? false : !! value
19      },
20      message: 'That {_field_} is unavailable.',
21    });
22  </script>
23
24  <!-- ... vue instance tags ... -->
25</body>

将定制规则添加到用户名字段:

1[label register.html]
2<validation-provider rules="required|checkuser">

现在,您已经为这些字段设置了要求电子邮件确认checkuser规则,所有规则都已建立,您现在可以开始显示错误消息。

步骤 5 – 访问 VeeValidate 错误和旗帜

VeeValidate 有错误可用. VeeValidate 也有状态信息的多个旗帜(https://logaretm.github.io/vee-validate/guide/state.html#flags). 您可以使用 Vue 的v-slot访问这些。

您还将使用 Vue 的v-show来显示 VeeValidate 错误消息,并使用 Bootstrap 的无效反馈类来定制错误。

此外,您还将使用 VeeValidate 标签为有效无效,并将 Vue 的v-bind:class和 Bootstrap 的is-validis-invalid类用于格式化这些字段:

 1[label register.html]
 2<validation-observer>
 3
 4  <form>
 5
 6    <div class="form-group">
 7      <validation-provider rules="required|alpha" v-slot="{ dirty, valid, invalid, errors }">
 8        <label for="name">Your Name</label>
 9        <div class="input-group">
10          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-user" aria-hidden="true"></i></span></span>
11          <input type="text" id="name" name="name" placeholder="Name" class="form-control" v-model="name" v-bind:class="{ 'is-valid': dirty && valid, 'is-invalid': dirty && invalid }" />
12        </div>
13        <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div>
14      </validation-provider>
15    </div>
16
17    <div class="form-group">
18      <validation-provider rules="required|email" v-slot="{ dirty, valid, invalid, errors }">
19        <label for="email">Your Email</label>
20        <div class="input-group">
21          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-envelope" aria-hidden="true"></i></span></span>
22          <input type="email" id="email" name="email" placeholder="[email protected]" class="form-control" v-model="email" v-bind:class="{ 'is-valid': dirty && valid, 'is-invalid': dirty && invalid }" />
23        </div>
24        <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div>
25      </validation-provider>
26    </div>
27
28    <div class="form-group">
29      <validation-provider rules="required|checkuser" v-slot="{ dirty, valid, invalid, errors }">
30        <label for="username">Username</label>
31        <div class="input-group">
32          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-users" aria-hidden="true"></i></span></span>
33          <input type="text" id="username" name="username" placeholder="Enter your username" class="form-control" v-model="username" v-bind:class="{ 'is-valid': dirty && valid, 'is-invalid': dirty && invalid }" />
34        </div>
35        <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div>
36      </validation-provider>
37    </div>
38
39    <div class="form-group">
40      <validation-provider rules="required|min:6" vid="password" v-slot="{ dirty, valid, invalid, errors }">
41        <label for="password">Password</label>
42        <div class="input-group">
43          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span>
44          <input type="password" id="password" name="password" placeholder="Enter a password" class="form-control" v-model="password" v-bind:class="{ 'is-valid': dirty && valid, 'is-invalid': dirty && invalid }" />
45        </div>
46        <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div>
47      </validation-provider>
48    </div>
49
50    <div class="form-group">
51      <validation-provider rules="required|confirmed:password" v-slot="{ dirty, valid, invalid, errors }">
52        <label for="password_confirmation">Confirm Password</label>
53        <div class="input-group">
54          <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span>
55          <input type="password" id="password_confirmation" name="password_confirmation" placeholder="Re-type password" class="form-control" v-model="password_confirmation" v-bind:class="{ 'is-valid': dirty && valid, 'is-invalid': dirty && invalid }" />
56        </div>
57        <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div>
58      </validation-provider>
59    </div>
60
61    <div class="form-group">
62      <button type="submit" class="btn btn-block btn-lg btn-primary">Register</button>
63    </div>
64
65  </form>
66
67</validation-observer>

在此时,您可以访问,有效,无效错误。您添加了逻辑来显示相关字段中的错误消息作为反馈。如果该字段与它交互并无效,则将应用 Bootstrap 的无效类别。

在下一步,您将处理提交表格。

步骤6 - 处理表格提交

VeeValidate 还为 ValidationObserver 提供一个无效旗帜和一个handleSubmit 函数,您可以使用 Vue 的v-slot 访问这些功能:

1[label register.html]
2<validation-observer v-slot="{ invalid, handleSubmit }">

使用 Vue 的事件编辑器来捕捉表单提交的@submit.prevent。您还将使用 VeeValidate 的HandleSubmit来阻止表单提交,直到所有字段都有效:

1[label register.html]
2<form @submit.prevent="handleSubmit(onSubmit)">

这将调用onSubmit,可以定义为console.log消息:

 1[label register.html]
 2<script>
 3  const signupForm = new Vue({
 4    el: '#signup-form',
 5    data: {
 6      name: '',
 7      email: '',
 8      username: '',
 9      password: '',
10      password_confirmation: ''
11    },
12    methods: {
13      onSubmit: function() {
14        console.log('Form has been submitted!');
15      }
16    }
17  });
18</script>

保持<按钮>处于禁用状态,以便在任何字段无效时不会提交信息:

1[label register.html]
2<button type="submit" class="btn btn-block btn-lg btn-primary" v-bind:disabled="invalid">Register</button>

在此时,您可以在网页浏览器中打开register.html,并与表单进行交互,以测试验证。

结论

在本教程中,您展示了如何使用模板驱动的方法验证表单输入.VeeValidate 允许您用现有规则验证表单输入,扩展新规则,显示错误,并处理表单提交。

如果您想了解有关 Vue.js 的更多信息,请参阅 我们的 Vue.js 主题页面以获取练习和编程项目。

Published At
Categories with 技术
comments powered by Disqus