Vue.jsでVuelidateを使ってバリデーションする(バリデーターを5つ)

Vue.js Vue.js

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) },
}

それぞれのバリデーションルールはスクリプトの最初の方にインポートしています。
バリデーションの意味は下記のような感じになります。

項目 チェック内容
email メールアドレスの形式が正しいか
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>

テキストボックスに作成したtestEmailv-modelを使用して紐づけています。
その下のタグが重要で、エラーがあった場合はv-forしているdivタグの中身が評価されて表示されます。

testEmailにエラーがあった場合はv$.testEmail.$errorsに配列形式でデータが入ってきます。
error.$validatorでエラーのあったバリデーターがわかります。
ここではemailバリデーターにエラーがあった場合「メールアドレスの形式が正しくありません。」という表示にしています。

今回は5つのタイプのバリデーターを使いましたが、他にも種類があり下記の公式ページに書いています。
Validators | Vuelidate
A simple, but powerful, lightweight model-based validation for Vue.js 3 and 2.

動作確認

最初は空で下記のように表示されます。
バリデーションのエラーがないため、それぞれの$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でバリデーションを検討している場合は一度試してみてください。

コメント

タイトルとURLをコピーしました