大ちゃんの駆け出し技術ブログ

RUNTEQ受講生のかわいいといわれるアウトプットブログ

【Vue】VeeValidate

はじめに

こんにちは!大ちゃんの駆け出し技術ブログです。

本日はveeValidateについてのアウトプットです。

これはフォームを入力時にフロント側でバリデーションしてくれる機能ですね。

これを使うと以下のようにリアルタイムでバリデーションのメッセージが表示されます。

https://i.gyazo.com/99e49e885344a47e0ea6641cc550bdbb.gif

今回はこれを紹介しますが、表示している画面が自分のPFの画面のため、コードを公開したくありません。そこで、サンプルコードを使用して説明します。

今回はveeValidateを導入するにあたって既に用意されているコンポーネントを2つ紹介します。基本は公式の通りに導入します。

Getting Started

インストール

まずインストール方法ですが、自分はrailsのアプリでwebpackerを使っていますので、yarnを使用してインストールします。

$ yarn add vee-validate

次にJSファイルを作成し、以下の3つをimportします。

  • ValidationProvider
  • ValidationObserver
  • extend
// app/javascript/plugins/vee-validate.js
import { ValidationProvider, ValidationObserver, extend } from "vee-validate";
import { required, max } from "vee-validate/dist/rules";

export default {
  components: {
    ValidationProvider,
    ValidationObserver,
  },
};

上述しました2つのコンポーネントというのはValidationProvider、ValidationObserverのことです。

※ extendに関しては後で記載します。

これらをメインで使用しているJSファイルでimportするためにexportをしています。

ではメインで使用しているJSファイルでimportします。

import veeValidate from "../plugins/vee-validate"
Vue.mixin(veeValidate)

Vue.mixinについては公式を参照したところ下記の記述があります。

グローバルにミックスインを適用することもできます。使用に注意してください!一度、グローバルにミックスインを適用すると、それはその後に作成する全ての Vue インスタンスに影響します。適切に使用されるとき、これはカスタムオプションに対して処理ロジックを注入するために使用することができます。

ミックスイン - Vue.js

グローバルミックスインという機能で、どこのVueインスタンスでも使用することができるようになります。よってveeValidateをどこのコンポーネントでも使用可能になりました。

(グローバルミックスイン自体にはVueインスタンス全体に影響があるので注意が必要ですが、今回のようなフォームへのバリデーションという複数のページで使用されると予想されるものは問題ないのかなと思っています。)

これでインストールの手順は完了です。

Validation Provider

Validation Provider | VeeValidate

Validation Providerは公式の例を使って説明します。

<template>
  <ValidationProvider rules="required" v-slot="{ errors }">
    <input v-model="value" type="text">
    <span id="error">{{ errors[0] }}</span>
  </ValidationProvider>
</template>

<script>
import { ValidationProvider } from 'vee-validate';

export default {
  components: {
    ValidationProvider
  }
};
</script>

ValidationProviderプラグインとして用意されているコンポーネントですので、コンポーネントとして登録してあります。これはグローバルミックスインを使用しない方法ですね。グローバルミックインをした場合、scriptタグの中にコンポーネントを登録する必要はありません。

[使用例]

<ValidationProvider rules="required" v-slot="{ errors }">
  <input v-model="value" type="text">
  <span id="error">{{ errors[0] }}</span>
</ValidationProvider>

ValidationProviderコンポーネントをフォームに対して挟むようにして設置します。コンポーネントにあるrules="required"ですが、これはrules="検証ルール"と記述することで検証ルールを指定しています。requiredは検証中のフィールドに空の値を入力できないというルールを表しています。

他にもこのルールに関してはたくさんありますが、今回は1番シンプルなrequiredのみを使用しています。他のルールについては以下のページで確認できます。

Available Rules | VeeValidate

そして検証ルールに沿わない、つまりフォームが未入力となっているとv-slot="{ errors }のerrorsの値が{{ errors[0] }}の部分に表示されるという仕組みです。slotに関してはこの間記事で説明したので割愛します。

これによりフォームが未入力となっていると検証メッセージが出ます。

extend

しかし、ValidationProviderデフォルトで用意されているメッセージ以外の独自メッセージも表示したいとします。例えば、自分が今回実装したメッセージのように「~してね」みたいなメッセージはデフォルトでは表示できません。

[再掲]

https://i.gyazo.com/99e49e885344a47e0ea6641cc550bdbb.gif

つまり上記のメッセージは、独自メッセージを作成したために表示できているということです。

そしてそれを可能にするのが先ほど挙げたextendになります。

import { ValidationProvider, ValidationObserver, extend } from "vee-validate";

extendをインポートすることで、カスタムメッセージを行えます。

その方法は同一ファイル内でカスタムメッセージをextendします。

import { ValidationProvider, ValidationObserver, extend } from "vee-validate";

extend("select_required", { // ルールの名前
  ...required, // 追加する検証ルールの種類
  message: "{_field_}を選択してね", // 表示するメッセージ
});

select_requiredはrulesの属性で指定する時に使用するルールの名前になります。rules="select_required"で定義するカスタムメッセージが表示できるということになります。

<ValidationProvider
  v-slot="{ errors }"
  rules="select_required"
>

2行目の...requiredですが、こちらはデフォルトの検証ルールの中でどのルールに該当するかということを示します。今回の場合は未入力時の検証ルールですので、requiredを指定します。例えばこれが「~文字以上入力してね」みたいな文字数の検証ルールの場合、requiredではなくminという検証ルールを指定します。

※ スプレッド構文(...)を使っている理由はわかりませんが、、、

最後に表示するメッセージを指定します。{_field_}の箇所はValidationProviderコンポーネントname属性で指定することで表示できます。例えば、以下のようにname属性に「性別」を指定した場合、「性別を選択してね」という文字がエラーメッセージとして表示されます。

<ValidationProvider
  v-slot="{ errors }"
  name="性別"
  rules="select_required"
>

ValidationObserver

最後にValidationObserverです。これの役割は検証エラーが出ている時にフォームの送信の実行ができないようにします。

ValidationObserverがないと、たとえエラーメッセージが表示されていてもフォームの送信ができてしまいます。

https://i.gyazo.com/9a985cb32ba7cf188020aaa82a17d1b6.gif

エラーメッセージが消えるまでこのボタンを押せないようにするためにValidationObserverが必要です

しかし実は実装は簡単で以下のようにフォームの間をValidationObserverコンポーネントで囲ってあげるだけです。

<ValidationObserver ref="observer" v-slot="{ invalid }">
    <ValidationProvider rules="required" v-slot="{ errors }">
      <input v-model="value" type="text">
      <span id="error">{{ errors[0] }}</span>
        <v-btn :disabled="invalid">入力完了!</v-btn>
    </ValidationProvider>
</ValidationObserver>

ref="observer" v-slot="{ invalid }"は必須です。invalidを挟み込むための箇所は、フォームの送信部分です。

v-btn :disabled="invalid">

これを行うことで、ValidationProviderで検証エラーが出ている場合、disabledが有効となり、ボタンが押せない状態になります。そして、エラーが消えたらdisabledが無効になります。

https://i.gyazo.com/df25859684d6249c511985171354ec37.gif

今回は以上です!