Vue.jsでフォームを検証する方法
序章
フォーム検証は、フォームフィールド検証とも呼ばれ、ユーザーがWebフォームのすべての必須フィールドに入力することを保証します。 フィールドに無効な値がある場合、エラーメッセージが表示され、値がすべてのルールを満たすまでフォームの送信が妨げられます。
テンプレート駆動型検証は、ディレクティブを使用して検証ルールをフォーム要素に直接設定するフォーム検証の一種です。
テンプレート駆動型の検証をVue.jsに実装するには、VeeValidateを使用できます。 VeeValidateは、入力フィールドを検証してエラーを表示できるようにするVue.jsのプラグインです。
これは、このチュートリアルで作成するもののアニメーション画像です。
このチュートリアルの最後に、VeeValidateを使用して入力フィールドを検証する登録フォームがあります。
前提条件
このチュートリアルは、JavaScriptの文字列とオブジェクトの知識があることを前提としています。 Vueにある程度精通していると有益ですが、必須ではありません。 Javascriptの詳細については、Javascriptでコーディングする方法シリーズをご覧ください。
さまざまなクラウドホストライブラリへの参照を含む単一のローカルHTMLファイルの構築に焦点を当てます。 @vue/cli
を使用してVueプロジェクトを作成し、パッケージマネージャーを使用してvee-validate
をインストールすることができます。 ただし、そのアプローチはこのチュートリアルの範囲外です。
ステップ1—VeeValidateを使用してVue.jsプロジェクトを設定する
Vue.jsフレームワークとVeeValidateライブラリが必要になります。
まず、端末を使用してregister.html
という名前の新しいファイルを作成します。
nano register.html
そして、ウェブページの初期コードを追加します。
register.html
<html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Vue Template Form Validation</title> </head> <body> <!-- ... --> </body> </html>
Vue.jsのブラウザービルドは、cdnjs
から入手できます。 VeeValidateのブラウザビルドは、jsdelivr
から入手できます。 register.html
ファイルの<body>
に両方を追加します。
register.html
<body> <!-- include the Vue.js framework --> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> <!-- include the VeeValidate library --> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vee-validate.min.js"></script> </body>
これらのファイルは、CDN(コンテンツ配信ネットワーク)によって提供されます。 ローカルにダウンロードまたは保存するものはありません。
これで、Vue.jsとVeeValidateの最新の安定したバージョン(この記事の執筆時点)を使用する準備ができたWebページができました。
BootstrapとFontAwesomeの追加
スタイリングを確立するには、Bootstrapを使用できます。 図像を追加するには、 FontAwesomeを利用することもできます。
BootstrapおよびFontAwesomeのブラウザビルドは、BootstrapCDN
から入手できます。 register.html
ファイルの<head>
に両方を追加します。
register.html
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Vue Template Form Validation</title> <!-- include the Bootsrap framework --> <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"> <!-- include Font Awesome --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous"> </head>
この時点で、Vue、VeeValidate、Bootstrap、およびFontAwesomeがあります。 次に、検証するフォームを作成します。
フォームマークアップの作成
このサンプルフォームは、ユーザーから5つの情報を求めます。 name
、email
、username
、password
、およびpassword_confirmation
が必要になります。
まず、フォームの初期マークアップを、<script>
タグの前のregister.html
ファイルの<body>
に追加します。
register.html
<body> <div class="container my-3"> <div class="row justify-content-around"> <div class="col-6 rounded shadow"> <h1 class="py-3">Sign up once and watch any of our free demos.</h1> <div id="signup-form"> <form> <!-- ... form fields ... --> </form> </div> </div> </div> </div> <!-- ... library script tags ... --> </body>
このコードは、空の<form>
を確立し、レイアウトと外観にいくつかのBootstrapユーティリティを使用します。
次に、フォームフィールドを<form>
に追加します。 name
のフィールドから始めます。
register.html
<form> <div class="form-group"> <label for="name">Your Name</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-user" aria-hidden="true"></i></span></span> <input type="text" id="name" name="name" placeholder="Name" class="form-control" /> </div> </div> </form>
このコードは、name
用の<label>
、fa-user
用のFontAwesomeアイコン、およびname
用の<input>
を作成します。
他の情報(email
、username
、password
、およびpassword_confirmation
)についても、<form>
に同様の追加を行うことができます。
register.html
<form> <!-- ... name ... --> <div class="form-group"> <label for="email">Your Email</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-envelope" aria-hidden="true"></i></span></span> <input type="email" id="email" name="email" placeholder="[email protected]" class="form-control" /> </div> </div> <div class="form-group"> <label for="username">Username</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-users" aria-hidden="true"></i></span></span> <input type="text" id="username" name="username" placeholder="Enter your username" class="form-control" /> </div> </div> <div class="form-group"> <label for="password">Password</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span> <input type="password" id="password" name="password" placeholder="Enter a password" class="form-control" /> </div> </div> <div class="form-group"> <label for="password_confirmation">Confirm Password</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span> <input type="password" id="password_confirmation" name="password_confirmation" placeholder="Re-type password" class="form-control" /> </div> </div> </form>
このコードは、<label>
、Font Awesomeアイコン、および<input>
を作成します。 各入力には、固有のid
およびname
があります。
<form>
を完了するための登録ボタンを追加します:
register.html
<form> <!-- ... form fields ... --> <div class="form-group"> <button type="submit" class="btn btn-block btn-lg btn-primary">Register</button> </div> </form>
このコードは、ブートストラップスタイルを使用して大きな送信ボタンを作成します。
ウェブブラウザでregister.html
を開いて、アプリの進行状況を確認できます。
ステップ2—Vueインスタンスの作成とマウント
次に、Vueインスタンスを作成し、#signup-form
にマウントします。
<body>
の最後に新しい<script>
タグを追加し、signupForm
を定義します。
register.html
<body> <!-- ... form ... --> <!-- ... library script tags ... --> <script> const signupForm = new Vue({ el: '#signup-form' }); </script> </body>
data
オブジェクトにプロパティを追加します。
register.html
<body> <!-- ... form ... --> <!-- ... library script tags ... --> <script> const signupForm = new Vue({ el: '#signup-form', data: { name: '', email: '', username: '', password: '', password_confirmation: '' } }); </script> </body>
次に、各フィールドのv-model
でプロパティを参照します。
name
フィールドに、以下を追加します。
register.html
<input type="text" id="name" name="name" placeholder="Name" class="form-control" v-model="name" />
email
フィールドに、以下を追加します。
register.html
<input type="email" id="email" name="email" placeholder="[email protected]" class="form-control" v-model="email" />
username
フィールドに、以下を追加します。
register.html
<input type="text" id="username" name="username" placeholder="Enter your username" class="form-control" v-model="username" />
password
フィールドに、以下を追加します。
register.html
<input type="password" id="password" name="password" placeholder="Enter a password" class="form-control" v-model="password" />
最後に、password_confirmation
フィールドに、以下を追加します。
register.html
<input type="password" id="password_confirmation" name="password_confirmation" placeholder="Re-type password" class="form-control" v-model="password_confirmation" />
この時点で、name
、email
、username
、password
、およびpassword_confirmation
のモデルを持つVueインスタンスがあります。
ステップ3—ValidationObserver
とValdiationProvider
を追加します
次に、ValidationObserver
とValidationProvider
を登録する必要があります。
<body>
の最後にある新しい<script>
タグに両方を追加できます。
register.html
<body> <!-- ... form ... --> <!-- ... library script tags ... --> <script> Vue.component('validation-observer', VeeValidate.ValidationObserver); Vue.component('validation-provider', VeeValidate.ValidationProvider); </script> <!-- ... vue instance script tag ... --> </body>
これで、<validation-observer>
を使用して、<form>
全体をラップできます。 また、<validation-provider>
を使用して、フィールドを折り返すことができます。
register.html
<validation-observer> <form> <div class="form-group"> <validation-provider> <label for="name">Your Name</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-user" aria-hidden="true"></i></span></span> <input type="text" id="name" name="name" placeholder="Name" class="form-control" v-model="name" /> </div> </validation-provider> </div> <div class="form-group"> <validation-provider> <label for="email">Your Email</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-envelope" aria-hidden="true"></i></span></span> <input type="email" id="email" name="email" placeholder="[email protected]" class="form-control" v-model="email" /> </div> </validation-provider> </div> <div class="form-group"> <validation-provider> <label for="username">Username</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-users" aria-hidden="true"></i></span></span> <input type="text" id="username" name="username" placeholder="Enter your username" class="form-control" v-model="username" /> </div> </validation-provider> </div> <div class="form-group"> <validation-provider> <label for="password">Password</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span> <input type="password" id="password" name="password" placeholder="Enter a password" class="form-control" v-model="password" /> </div> </validation-provider> </div> <div class="form-group"> <validation-provider> <label for="password_confirmation">Confirm Password</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span> <input type="password" id="password_confirmation" name="password_confirmation" placeholder="Re-type password" class="form-control" v-model="password_confirmation" /> </div> </validation-provider> </div> <div class="form-group"> <button type="submit" class="btn btn-block btn-lg btn-primary">Register</button> </div> </form> </validation-observer>
これで、<validation-observer>
と<valdiation-provider>
で作成されたフォームができました。
ステップ4—VeeValidateルールの使用
VeeValidateルールは、1つ以上のフィールドに入力できるものに制限または条件を設定します。 検証が必要なフィールドを含むレコードを更新すると、検証ルールがチェックされます。 ルールに違反すると、トラップ可能なエラーが発生します。
たとえば、required
バリデーターを使用できます。
<validation-provider rules="required">
パイプ文字(|
)で区切られた複数の検証に合格できます。
たとえば、required
およびemail
バリデーターを使用できます。
<validation-provider rules="required|email">
または、オブジェクトを渡して柔軟性を高めることもできます。
<validation-provider :rules="{ required: true, email: true, regex: /[0-9]+/ }">
これで、入力が変更されるたびに、バリデーターは検証のリストを左から右に実行し、入力が検証に失敗するたびにエラーヘルパーオブジェクトにデータを入力します。
このチュートリアルを書いている時点で、VeeValidateにはフォーム検証用の 30のルールがあり、独自のルールを作成するオプションがあります。
ルールの適用
次に、VeeValidateRules
をインポートする必要があります。
register.html
ファイルの<body>
の最後にある新しい<script>
タグに追加できます。
register.html
<body> <!-- ... form ... --> <!-- ... library script tags ... --> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/rules.umd.js"></script> <!-- ... vue instance tags ... --> </body>
次に、ルールをループして、すべてを使用可能にすることができます。
register.html
<body> <!-- ... form ... --> <!-- ... library script tags ... --> <script> Object.keys(VeeValidateRules).forEach(rule => { VeeValidate.extend(rule, VeeValidateRules[rule]); }); </script> <!-- ... vue instance tags ... --> </body>
そして、すべての入力にrequired
ルールを適用します。
register.html
<validation-provider rules="required">
複数のルールを適用する
email
の場合、有効な電子メールアドレスのルールも適用します。
register.html
<validation-provider rules="required|email">
password
の場合、6
文字の最小長のルールも適用します。
register.html
<validation-provider rules="required|min:6">
これで、フィールドにrequired
、email
、およびmin
のルールが設定されました。
クロスフィールド検証の適用
password_confirmation
の場合、有効にするにはpassword
の値と一致する必要があります。 これを実現するには、ValidationObserver
を使用します。これにより、password_confirmation
がpassword
を認識できるようになります。
vid
をpassword
フィールドに追加して、password_confirmed
にターゲットを設定します。
register.html
<validation-provider rules="required|min:6" vid="password">
confirmed
ルールをpassword_confirmation
フィールドに追加して、password_confirmed
がその値をpassword
の値と比較するようにします。
register.html
<validation-provider rules="required|confirmed:password">
これで、フィールドにrequired
、email
、min
、およびconfirmed
のルールが設定されました。
カスタムルールの追加
VeeValidateを使用すると、extend
およびvalidate
を使用してカスタム検証ルールとメッセージを作成できます。
ユーザーが制限された単語で登録できないようにするルールを追加します。 この例では、ユーザーがadmin
、password
、およびadministrator
という単語を使用することを制限します。
register.html
<body> <!-- ... form ... --> <!-- ... library script tags ... --> <script> // Declare an array of usernames that are invalid. const restricted_usernames = [ 'admin', 'password', 'administrator' ]; // Extend the custom rule. VeeValidate.extend('checkuser', { name: 'Restricted Usernames', validate: value => { return restricted_usernames.includes(value.toLowerCase()) ? false : !! value }, message: 'That {_field_} is unavailable.', }); </script> <!-- ... vue instance tags ... --> </body>
カスタムルールをusername
フィールドに追加します。
register.html
<validation-provider rules="required|checkuser">
これで、フィールドにrequired
、email
、min
、confirmed
、およびcheckuser
のルールが設定されました。 ルールがすべて確立され、エラーメッセージの表示を開始できるようになりました。
ステップ5—VeeValidateエラーとフラグへのアクセス
VeeValidateではerrors
を利用できます。 VeeValidateには、状態情報用の複数のフラグもあります。 これらには、Vueのv-slot
を使用してアクセスできます。
また、Vueのv-show
を使用してVeeValidateエラーメッセージを表示し、Bootstrapのinvalid-feedback
クラスを使用してエラーのスタイルを設定します。
さらに、dirty
、valid
、およびinvalid
のVeeValidateフラグを、Vueのv-bind:class
およびBootstrapのis-valid
およびis-invalid
フィールドをスタイリングするためのクラス:
register.html
<validation-observer> <form> <div class="form-group"> <validation-provider rules="required|alpha" v-slot="{ dirty, valid, invalid, errors }"> <label for="name">Your Name</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-user" aria-hidden="true"></i></span></span> <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 }" /> </div> <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div> </validation-provider> </div> <div class="form-group"> <validation-provider rules="required|email" v-slot="{ dirty, valid, invalid, errors }"> <label for="email">Your Email</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-envelope" aria-hidden="true"></i></span></span> <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 }" /> </div> <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div> </validation-provider> </div> <div class="form-group"> <validation-provider rules="required|checkuser" v-slot="{ dirty, valid, invalid, errors }"> <label for="username">Username</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-users" aria-hidden="true"></i></span></span> <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 }" /> </div> <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div> </validation-provider> </div> <div class="form-group"> <validation-provider rules="required|min:6" vid="password" v-slot="{ dirty, valid, invalid, errors }"> <label for="password">Password</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span> <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 }" /> </div> <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div> </validation-provider> </div> <div class="form-group"> <validation-provider rules="required|confirmed:password" v-slot="{ dirty, valid, invalid, errors }"> <label for="password_confirmation">Confirm Password</label> <div class="input-group"> <span class="input-group-prepend"><span class="input-group-text"><i class="fa fa-lock" aria-hidden="true"></i></span></span> <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 }" /> </div> <div class="invalid-feedback d-inline-block" v-show="errors">{{ errors[0] }}</div> </validation-provider> </div> <div class="form-group"> <button type="submit" class="btn btn-block btn-lg btn-primary">Register</button> </div> </form> </validation-observer>
この時点で、dirty
、valid
、invalid
、およびerrors
にアクセスできます。 関連するフィールドの下にフィードバックとしてエラーメッセージを表示するロジックを追加しました。 フィールドが相互作用して無効な場合、Bootstrapのis-invalid
クラスが適用されます。 フィールドが相互作用して有効な場合、Bootstrapのis-valid
クラスが適用されます。
次のステップでは、フォームの送信を処理します。
ステップ6—フォーム送信の処理
VeeValidateは、ValidationObserver
およびhandleSubmit
関数のinvalid
フラグも提供します。 これらには、Vueのv-slot
を使用してアクセスできます。
register.html
<validation-observer v-slot="{ invalid, handleSubmit }">
Vueのイベント修飾子を使用して、@submit.prevent
でフォーム送信をキャプチャします。 また、VeeValidateのhandleSubmit
を使用して、すべてのフィールドが有効になるまでフォームの送信を防止します。
register.html
<form @submit.prevent="handleSubmit(onSubmit)">
これにより、onSubmit
が呼び出されます。これは、console.log
メッセージとして定義できます。
register.html
<script> const signupForm = new Vue({ el: '#signup-form', data: { name: '', email: '', username: '', password: '', password_confirmation: '' }, methods: { onSubmit: function() { console.log('Form has been submitted!'); } } }); </script>
<button>
をdisabled
状態に保ち、フィールドがinvalid
のときに情報を送信しないようにします。
register.html
<button type="submit" class="btn btn-block btn-lg btn-primary" v-bind:disabled="invalid">Register</button>
この時点で、Webブラウザでregister.html
を開き、フォームを操作して検証をテストできます。
結論
このチュートリアルでは、テンプレート駆動型アプローチを使用してフォーム入力を検証する方法を示しました。 VeeValidateを使用すると、既存のルールを使用してフォーム入力を検証し、新しいルールを拡張し、エラーを表示し、フォーム送信を処理できます。
Vue.jsの詳細については、Vue.jsトピックページで演習とプログラミングプロジェクトを確認してください。