Vue.jsをフロントで使用しているときに、Vuelidateを使ってバリデーションする方法を書いています。
サンプルコードにはVue.jsのバージョン3のComposition APIを使っています。
Vuelidateについて
VuelidateはVue.jsでフロントエンドをバリデーションするときに使うことができるライブラリです。
導入すると、フロントエンドでのバリデーションが簡単になります。
Vuelidateを使ったサンプル
今回はVuelidateを使って、「required・integer・email・minLength・maxLength」の5つバリデータを試してみました。
下記のように5つのテキストエリアを作ってテストしています。
「validateテスト」ボタンを押すと、バリデーションが動きます。
この画面のコードは下記になります。
<template>
<div class="p-3 m-3 border rounded-lg">
<div>
<input class="mt-2 p-2 rounded border border-blue-300 w-9/12" type="text" v-model="testEmail" placeholder="email address" />
<div v-for="(error, index) in v$.testEmail.$errors" :key="index" class="text-xs text-red-500 mb-2">
<div v-if="error.$validator == 'email'">メールアドレスの形式が正しくありません。</div>
</div>
<input class="mt-2 p-2 rounded border border-blue-300 w-9/12" type="text" v-model="testMinLength" placeholder="min length 5" />
<div v-for="(error, index) in v$.testMinLength.$errors" :key="index" class="text-xs text-red-500 mb-2">
<div v-if="error.$validator == 'minLength'">5文字以上を入力してください。</div>
</div>
<input class="mt-2 p-2 rounded border border-blue-300 w-9/12" type="text" v-model="testMaxLength" placeholder="max length 10" />
<div v-for="(error, index) in v$.testMaxLength.$errors" :key="index" class="text-xs text-red-500 mb-2">
<div v-if="error.$validator == 'maxLength'">10文字以上を入力してください。</div>
</div>
<input class="mt-2 p-2 rounded border border-blue-300 w-9/12" type="text" v-model="testRequired" placeholder="required" />
<div v-for="(error, index) in v$.testRequired.$errors" :key="index" class="text-xs text-red-500 mb-2">
<div v-if="error.$validator == 'required'">必須入力です。</div>
</div>
<input class="mt-2 p-2 rounded border border-blue-300 w-9/12" type="text" v-model="testInteger" placeholder="integer" />
<div v-for="(error, index) in v$.testInteger.$errors" :key="index" class="text-xs text-red-500 mb-2">
<div v-if="error.$validator == 'required'">必須入力です。</div>
<div v-if="error.$validator == 'integer'">数値(整数)のみを入力してください。</div>
<div v-if="error.$validator == 'minLength'">3文字以上を入力してください。</div>
</div>
</div>
<button
@click="validateTest"
class="bg-blue-500 hover:bg-blue-400 text-white font-bold py-2 px-4 mt-3 border-b-4 border-blue-700 hover:border-blue-500 rounded"
>validateテスト</button>
</div>
</template>
<script>
import { ref } from 'vue'
import { useVuelidate } from '@vuelidate/core'
import { required, email, integer, maxLength, minLength } from '@vuelidate/validators'
export default ({
setup() {
const testEmail = ref('')
const testMinLength = ref('')
const testMaxLength = ref('')
const testRequired = ref('')
const testInteger = ref('')
const rules = {
testEmail: { email },
testMinLength: { minLength: minLength(5) },
testMaxLength: { maxLength: maxLength(10) },
testRequired: { required },
testInteger: { integer, required, minLength: minLength(3) },
}
const v$ = useVuelidate(rules, { testEmail, testMinLength, testMaxLength, testRequired, testInteger })
const validateTest = async () => {
const isFormCorrect = await v$.value.$validate()
if (!isFormCorrect) return
// バリデーションエラーじゃない場合にやりたい処理
}
return {
testEmail,
testInteger,
testMinLength,
testMaxLength,
testRequired,
validateTest,
v$
}
}
})
</script>
解説
スクリプトの方から解説していきます。
テキストボックスに対する変数を用意する
最初に5つの変数を作成しています。
この変数が画面のテキストボックスにv-model
でそれぞれ紐づけられます。
const testEmail = ref('')
const testMinLength = ref('')
// ----- 省略 -----
バリデーションルールの作成
次にrules
という変数を作っています。
これがまさにバリデーションルールになります。
const rules = {
testEmail: { email },
testMinLength: { minLength: minLength(5) },
testMaxLength: { maxLength: maxLength(10) },
testRequired: { required },
testInteger: { integer, required, minLength: minLength(3) },
}
それぞれのバリデーションルールはスクリプトの最初の方にインポートしています。
バリデーションの意味は下記のような感じになります。
項目 | チェック内容 |
---|---|
メールアドレスの形式が正しいか | |
minLength | 指定された桁数以上か |
maxLength | 指定された桁数以下か |
required | 必須入力。入力されているか |
integer | 整数以外が入力されていないか |
testInteger
変数に対しては複数のバリデーションをかけています。
必須入力で、数値そして最小値が3桁以上を入力しないとエラーになります。
useVuelidateしてバリデーション変数を作成する
次にuseVuelidate
しています。
これもスクリプトの最初の方で@vuelidate/core
からインポートしています。
第1引数にルールを入れて、第2引数にバリデーションで使う変数をオブジェクトで渡します。
const v$ = useVuelidate(rules, { testEmail, testMinLength, testMaxLength, testRequired, testInteger })
v$
という変数を作って、画面から使えるようにしています。
これでバリデーションする準備が完了です。
バリデーションする
「validateテスト」ボタンを押した時の挙動を下記のように書いています。
作成したv$
変数を使って、$validate()
を呼び出すとバリデーションを実行できます。
const validateTest = async () => {
const isFormCorrect = await v$.value.$validate()
if (!isFormCorrect) return
// バリデーションエラーじゃない場合にやりたい処理
}
問題がなければtrueが返ってきますが、エラーがある場合はfalseになります。
if(!isFormCorrect)
としているのでfalseになると、後続の処理を行うことが可能です。
この後にバリデーションエラーでない場合にやりたい処理を書くといいです。
Vuelidateでのエラー表示について
HTMLタグの箇所を説明します。
5つとも同じように書いているので、emailだけに絞って解説します。
コードは下記のようになっています。
<input class="mt-2 p-2 rounded border border-blue-300 w-9/12" type="text" v-model="testEmail" placeholder="email address" />
<div v-for="(error, index) in v$.testEmail.$errors" :key="index" class="text-xs text-red-500 mb-2">
<div v-if="error.$validator == 'email'">メールアドレスの形式が正しくありません。</div>
</div>
テキストボックスに作成したtestEmail
をv-model
を使用して紐づけています。
その下のタグが重要で、エラーがあった場合はv-for
しているdivタグの中身が評価されて表示されます。
testEmail
にエラーがあった場合はv$.testEmail.$errors
に配列形式でデータが入ってきます。
error.$validator
でエラーのあったバリデーターがわかります。
ここではemail
バリデーターにエラーがあった場合「メールアドレスの形式が正しくありません。」という表示にしています。
動作確認
最初は空で下記のように表示されます。
バリデーションのエラーがないため、それぞれの$errors
にデータが入っていない状態です。
下記のように入力します。
そしてバリデーションボタンを押すと…
このようにバリデーションされることが確認できました。
ちなみに、integerのように複数バリデーションしている箇所だと、エラーが複数あった場合は下記のように表示されます。
Vuelidateでフォーカスアウト時にバリデーションしたい
今回はボタンを押したときにバリデーションしました。
入力した時点やフォーカスアウトした時点でバリデーションしたいことがあると思います。
その場合は、下記のようにイベント時に$touth
を呼ぶようにします。
サンプルのメールアドレスの箇所で、フォーカスアウトした場合にバリデーションする例です。
<input type="text" v-model="testEmail" placeholder="email address" @blur="v$.testEmail.$touch">
@blur
でフォーカスアウト時を定義しています。
イベント発生時に、「作成したバリデーション変数($v)」の「v-modelの変数名」の$touch
を参照するようにしました。
こうするとフォーカスアウト時にバリデーションしてくれます。
スクリプト内でバリデーションエラーかどうかはv$.value.$validate()
で同じように判定することができます。
おわりに
今回はVuelidateを使って、バリデーションをする方法を書きましたがいかがでしたか。
私はVue.jsでバリデーションをするときに、最初はVeeValidateを使おうと思いました。
ですが、Composition APIで使う方法がよくわからなかったので、今回Vuelidateを使うことにしました…🤯
Vuelidateを使ってみましたが、シンプルな作りなので使いやすいなと感じました。
Vue.jsでバリデーションを検討している場合は一度試してみてください。
コメント