VeeValidateでVue.js用の超便利なバリデーションを実装する

2019年10月18日

VeeValidateとは

VeeValidateは、Vue.js用のリアルタイムバリデーションコンポーネントライブラリです。
ユーザーによって入力された値が不正な場合に、リアルタイムにエラーを表示させることができます。

バリデーションパターンは全部で27種類備えています。
さらにカスタムバリデーションとして、自作のバリデーションを実装することも可能です。

Vue.js用のバリデーションライブラリでは、最大の人気があります(vuelidateが肉薄してますが。
バリデーションライブラリで悩んだら、ひとまずこのライブラリを選択しておけば問題ありません。

 

【動画サイズ:154KB】

 

環境

この記事は、以下の管理人の検証環境にて記事にしています。

ライブラリの取得

ライブラリを取得するには、npm, yarn, CDNのどれか一つを使用します。

npm

npm i vee-validate --save 

yarn

yarn add vee-validate

CDN

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vee-validate.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/rules.umd.min.js"></script>

 

直接「VeeValidate」のリポジトリを取得する場合は、以下のURLから取得できます。

 

導入手順

管理人が行った、動作確認サンプルを実装するために、以下の手順でソースコードを導入していきます。
このサンプルでは、必須項目とメールアドレスのバリデーションを実装します。

 

ライブラリの呼び出し

まずライブラリを呼び出す為に、以下の2通りの呼び出しを選択します。
コンパイラを使用しない場合は、UMDを使ってください。

ES6等で実装する場合

import { extend, ValidationProvider, ValidationObserver } from 'vee-validate';
import { required, email } from 'vee-validate/dist/rules';
// バリデーションルール
extend('required', required);
extend('email', email);

UMDで実装する場合

const VeeValidate = window.VeeValidate;
// フィールド監視
const ValidationProvider = VeeValidate.ValidationProvider;
// フォーム監視
const ValidationObserver = VeeValidate.ValidationObserver;
// バリデーションルール
const VeeValidateRules = window.VeeValidateRules;
VeeValidate.extend('required', VeeValidateRules.required);
VeeValidate.extend('email', VeeValidateRules.email);

 

JavaScriptを設定

Vue.component に上記で取得した ValidationProvider ValidationObserver を読み込ませます。

この2つの使い分けは以下になります。

ポイント

  • ValidationProvider
    各フィールドを監視するのに使用します。

  • ValidationObserver
    フォーム全体を監視するのに使用します。入力フィールドのどれかでエラーが発生している時に、ボタンへdisabledを設定する時に使えます。
Vue.component('ValidationProvider', ValidationProvider);
Vue.component('ValidationObserver', ValidationObserver);

new Vue({
  el: '#app',
  data: {
    name: '',
    email: ''
  },
  methods: {
    submit: function(){
      alert('送信しました!');
    }
  }
});

 

テンプレートを準備

フォーム全体入力フィールドで別種のコンポーネントを設置します。

フォーム全体

まずフォーム全体を <ValidationObserver> で囲みます。
v-slot から ObserverProps を取得します。
ObserverProps には、 フォームの状態が格納されています(入力エラー発生など。
今回のサンプルでは、<button>に状態判定でdisabledを設定しました。

入力フィールド

次に各入力フィールドを  <ValidationProvider> で囲みます。
入力フィールドにバリデーションを設定するには、rules バリデーションルール名を設定します。
slot-scopeで渡されるProviderProps には、入力フィールドの状態が格納されています(入力エラー発生など。
ProviderProps.errors[0]のような形で出力をすると入力フィールドのエラーを表示させることが可能です。

ポイント

バリデーションルールを複数設定したい場合は、 | で区切ります。

 

※ サンプルはHTML直書きを想定しているため、ケバブケースに置き換えています。

<div id="app">
  <validation-observer ref="obs" v-slot="ObserverProps">
    <label>名前</label>
    <validation-provider name="名前" rules="required">
      <div slot-scope="ProviderProps">
        <input v-model="name">
        <p class="error">{{ ProviderProps.errors[0] }}</p>
      </div>
    </validation-provider>
    <label>メールアドレス</label>
    <validation-provider name="メールアドレス" rules="required|email">
      <div slot-scope="ProviderProps">
        <input v-model="email">
        <p class="error">{{ ProviderProps.errors[0] }}</p>
      </div>
    </validation-provider>
    <button type="button" @click="submit" :disabled="ObserverProps.invalid || !ObserverProps.validated">送信</button>
  </validation-observer>
</div>

 

サンプル

今回のソースを実際に触って確認できるようにデモを用意しました。

>>専用ページで確認する

 

バリデーションルール

VeeValidateで使用できるバリデーションルールを、視覚的に確認しやすいGifでまとめてみました。
一応、IE11対策をしたソースになっています。

本家の説明ページを確認する場合は、以下のURLより飛んでください。

 

alpha

検証中のフィールドには、アルファベット文字のみを含めることができます。

<ValidationProvider rules="alpha" v-slot="ProviderProps">
  <input v-model="value" type="text">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

alpha_dash

検証中のフィールドには、アルファベット文字、数字、ダッシュまたはアンダースコアが含めることができます。

<ValidationProvider rules="alpha_dash" v-slot="ProviderProps">
  <input v-model="value" type="text">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

alpha_num

検証中のフィールドには、アルファベット文字または数字を含めることができます。

<ValidationProvider rules="alpha_num" v-slot="ProviderProps">
  <input v-model="value" type="text">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

alpha_spaces

検証中のフィールドには、アルファベット文字または半角スペースを含めることができます。

<ValidationProvider rules="alpha_spaces" v-slot="ProviderProps">
  <input v-model="value" type="text">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

between

検証中のフィールドには、最小値と最大値で区切られた数値を設定することができます。

<ValidationProvider rules="between:1,11" v-slot="ProviderProps">
  <input v-model="value" type="text">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

confirmed

検証中のフィールドは、確認フィールドと同じ値を設定することができます。

<ValidationObserver>
  <ValidationProvider rules="confirmed:confirmation" v-slot="ProviderProps">
    <input v-model="value" type="text">
    <span>{{ ProviderProps.errors[0] }}</span>
  </ValidationProvider>
  <ValidationProvider v-slot="ProviderProps" vid="confirmation">
    <input v-model="confirmation" type="text">
    <span>{{ ProviderProps.errors[0] }}</span>
  </ValidationProvider>
</ValidationObserver>

 

digits

検証中のフィールドは、数値で指定された桁数を設定することができます。

<ValidationProvider rules="digits:3" v-slot="ProviderProps">
  <input v-model="value" type="text">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

dimensions

検証中のフィールドは、追加されるファイルが正確に指定された寸法を持つ画像(jpg、svg、jpeg、png、bmp、gif)を設定することができます。

<ValidationProvider rules="dimensions:150,150" v-slot="ProviderProps">
  <input type="file" @change="ProviderProps.validate">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

email

検証中のフィールドは、有効なメールアドレスを設定することができます。

<ValidationProvider rules="email" v-slot="ProviderProps">
  <input type="text" v-model="value">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

ext

検証中のフィールドに追加されるファイルには、指定された拡張子のいずれかが必要です。

<ValidationProvider rules="ext:jpg,png" v-slot="ProviderProps">
  <input type="file" @change="ProviderProps.validate">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

image

検証中のフィールドに追加されるファイルには、イメージMIMEタイプ(image / *)が必要です。

<ValidationProvider rules="image" v-slot="ProviderProps">
  <input type="file" @change="ProviderProps.validate">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

oneOf

検証中のフィールドには、指定されたリストにある値が必要です。チェックに二重等号使用します。

<ValidationProvider rules="oneOf:1,2,3" v-slot="ProviderProps">
  <select v-model="value">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
    <option value="4">Invalid</option>
  </select>
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

is

検証中のフィールドは、渡された最初の引数と等しくなければならず ===、等価性チェックに使用されます。このルールは、オブジェクト形式で使用するときにパスワードを確認するのに役立ちます。文字列形式を使用すると、引数が文字列として解析されるため、このルールを使用する場合はオブジェクト形式を使用してください。

<ValidationProvider rules="is:hello" v-slot="ProviderProps">
  <input type="text" v-model="value">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

length

検証中のフィールドは指定された長さである必要があります。

<validation-provider name="length" rules="length:4">
  <div slot-scope="ProviderProps">
    <input name="length" v-model="length">
    <p class="error">{{ ProviderProps.errors[0] }}</p>
  </div>
</validation-provider>

 

max

検証の長さのフィールドは、指定された長さを超えることはできません。

<ValidationProvider rules="max:4" v-slot="ProviderProps">
  <input type="text" v-model="value">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

max_value

検証中のフィールドは数値である必要があり、指定された値を超えてはなりません

<ValidationProvider rules="max_value:4" v-slot="ProviderProps">
  <input type="text" v-model="value">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

mimes

検証中のフィールドに追加されるファイルタイプには、指定されたMIMEタイプのいずれかが必要です。

<ValidationProvider rules="mimes:image/*" v-slot="ProviderProps">
  <input type="file" @change="ProviderProps.validate">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

min

検証の長さの下にあるフィールドは、指定された長さより小さくすることはできません

<ValidationProvider rules="min:4" v-slot="ProviderProps">
  <input type="text" v-model="value">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

min_value

検証中のフィールドは数値である必要があり、指定された値より小さくすることはできません

<ValidationProvider rules="min_value:4" v-slot="ProviderProps">
  <input type="text" v-model="value">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

excluded

検証中のフィールドは指定の値を除外して構成する必要があります。

<ValidationProvider name="excluded" rules="excluded:1,2,3,4">
  <div slot-scope="ProviderProps">
     <input name="excluded" v-model="excluded">
     <p class="error">{{ ProviderProps.errors[0] }}</p>
  </div>
</ValidationProvider>

 

numeric

検証中のフィールドは数字のみで構成する必要があります。

<ValidationProvider rules="numeric" v-slot="ProviderProps">
  <input type="text" v-model="value">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

regex

検証中のフィールドは、指定された正規表現と一致する必要があります。

<ValidationProvider :rules="{ regex: /^[0-9]+$/ }" v-slot="ProviderProps">
  <input type="text" v-model="value">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

required

検証中のフィールドには空でない値が必要です。デフォルトでは、「空の値」が必要な場合を除き、すべてのバリデーターは検証に合格します。これらの空の値は次のとおりです。空の文字列、undefinednull、空の配列。

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

 

required_if

検証中のフィールドは、ターゲットフィールド(最初の引数)が指定された値(他の引数)のいずれかに設定されている場合のみ空でない値を持つ必要があります。

<ValidationProvider rules="" vid="country" v-slot="x">
  <select v-model="country">
    <option value="US">United States</option>
    <option value="OTHER">Other country</option>
  </select>
</ValidationProvider>
<ValidationProvider rules="required_if:country,US" v-slot="ProviderProps">
  <input type="text" placeholder="state" v-model="state" />
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

size

検証中のフィールドに追加されるファイルサイズは、指定されたサイズ(キロバイト単位)を超えてはなりません

<ValidationProvider rules="size:100" v-slot="ProviderProps">
  <input type="file" @change="ProviderProps.validate">
  <span>{{ ProviderProps.errors[0] }}</span>
</ValidationProvider>

 

サンプル

各種バリデーションを実際に触って確認できるように、デモを用意しました。

>>専用ページで確認する

 

言語設定

バリデーションのメッセージは、基本が英語になっています。
これを日本国内で使うのは難しいので、メッセージを日本語に設定します。

 

ES6等の場合

import { localize } from 'vee-validate';
import ja from 'vee-validate/dist/locale/ja.json';
localize({ja});

 

UMDの場合

注意ポイント

localizeextend の後に設置しないと上手く動きません。

const ja = {
  "code": "ja",
  "messages": {
    "alpha": "{_field_}はアルファベットのみ使用できます",
    "alpha_num": "{_field_}は英数字のみ使用できます",
    "alpha_dash": "{_field_}は英数字とハイフン、アンダースコアのみ使用できます",
    "alpha_spaces": "{_field_}はアルファベットと空白のみ使用できます",
    "between": "{_field_}は{min}から{max}の間でなければなりません",
    "confirmed": "{_field_}が一致しません",
    "digits": "{_field_}は{length}桁の数字でなければなりません",
    "dimensions": "{_field_}は幅{width}px、高さ{height}px以内でなければなりません",
    "email": "{_field_}は有効なメールアドレスではありません",
    "excluded": "{_field_}は不正な値です",
    "ext": "{_field_}は有効なファイル形式ではありません",
    "image": "{_field_}は有効な画像形式ではありません",
    "is": "{_field_}が一致しません",
    "length": "{_field_}は{length}文字でなければなりません",
    "max_value": "{_field_}は{max}以下でなければなりません",
    "max": "{_field_}は{length}文字以内にしてください",
    "mimes": "{_field_}は有効なファイル形式ではありません",
    "min_value": "{_field_}は{min}以上でなければなりません",
    "min": "{_field_}は{length}文字以上でなければなりません",
    "numeric": "{_field_}は数字のみ使用できます",
    "oneOf": "{_field_}は有効な値ではありません",
    "regex": "{_field_}のフォーマットが正しくありません",
    "required": "{_field_}は必須項目です",
    "required_if": "{_field_}は必須項目です",
    "size": "{_field_}は{size}KB以内でなければなりません"
  }
};

VeeValidate.localize('ja', ja);

 

カスタムルール

VeeValidateは自作のカスタムルールを設定することが可能です。

管理人が、カスタムルールを使おうとした時にだいぶ悩んだので、割とシンプルな実装サンプル付きの解説を記事にしてみました。
悩んでいる方は、以下の記事を確認してみてください。

 

基本設定

基本的なカスタムルールを設定する方法は以下の記事を参考にしてください。

VeeValidateのカスタムルールの設定方法(v3系)
参考VeeValidateのカスタムルールの設定方法(v3系)

VeeValidate公式ドキュメントのカスタムルールの設定方法が理解しづらすぎたので、見直すことが無いように設定方法を記事に残しておこうと思います。

続きを見る

 

クロスフィールド

フィールド同士を比較するようなカスタムルールを設定するには以下の記事を参考にしてください。

VeeValidateのクロスフィールドカスタムルールの設定方法(v3系)
参考VeeValidateのクロスフィールドのカスタムルール設定方法(v3系)

VeeValidate公式ドキュメントのカスタムルールの設定方法が理解しづらすぎたので、見直すことが無いように設定方法を記事に残しておこうと思います。今回は別のフィールドと比較検証するクロスフィールドカスタムルールの設定方法を記事にしようと思います。

続きを見る

 

IE11でエラーが発生した場合

VeeValidateIE11で使うとエラーが発生します。
対応方法は以下のページで公開してます。

参考VeeValidateがIE11で使えない時の対応方法

IE11でVeeValidateがエラーを発生させていることに気が付きました。polyfill.jsを呼び出してPromiseを設定してやります。これでIE11でもVeeValidateが使用できるようになります。

続きを見る

 

ユースケース

管理人が、フォームを作っている時に、割と出てくるけどVeeValidateを使う方法が分かりにくかった用法を記載していきます。

同意するチェックボックス

required ルールにオブジェクトで  allowFalse プロパティ false を設定する

  <validation-observer ref="obs" v-slot="ObserverProps">
    <div class="filed">
        <validation-provider name="required" :rules="{ required: { allowFalse: false } }">
          <div slot-scope="ProviderProps">
            <input type="checkbox" v-model="value" true-value="on" false-value="">同意する
            <p class="error">{{ ProviderProps.errors[0] }}</p>
          </div>
        </validation-provider>
    </div>   
    <button type="button" @click="submit" :disabled="!ObserverProps.valid">送信</button>
  </validation-observer>

 

その他選択時のテキスト入力

watch を使ってラジオボタンの入力値を監視します。
その他が設定された場合 this.$refs.obs.refs.required_other.validate() を使って強制的にバリデーションを起動しています。

  <validation-observer ref="obs" v-slot="ObserverProps">
    <div class="filed">
      <validation-provider name="required" rules="required" vid="required">
        <div slot-scope="ProviderProps">
          <div v-for="(item, index) in items">
              <input type="radio" name="required" v-model="value" :value="item" :key="index">
              {{item}}
          </div>
          <div>
              <input type="radio" name="required" v-model="value" value="other">
              その他      
          </div>
          <p class="error">{{ ProviderProps.errors[0] }}</p>
        </div>
      </validation-provider>
      <validation-provider name="required_other" rules="required_if:required,other">
        <div slot-scope="ProviderProps">
          <input type="text" name="required_other" v-model="value2" value="">
          <p class="error">{{ ProviderProps.errors[0] }}</p>
        </div>
      </validation-provider>
    </div>
    <button type="button" @click="submit" :disabled="!ObserverProps.valid">送信</button>
  </validation-observer>
let app = new Vue({
  el: '#app',
  data: {
    value: 'coffee',
    value2:'',
    items: ['coffee', 'tea', 'juice', 'beer', 'milk'],
  },
  methods: {
    submit: function(){
      alert('送信しました!');
    }
  },
  watch : {
    value: function(value){
      if(value == 'other')
        this.$refs.obs.refs.required_other.validate();
    }
  }
});

 

ページアクセス時のエラー判定

ページにアクセスしてすぐにバリデーションを判定を行いたい場合があります(ブラウザバックや編集ページなど。
そんな時は immediate プロパティを使用します。

//初回アクセス時(検証しない)
<ValidationProvider rules="required" :immediate="false" v-slot="{ errors }">
<!-- -->
</ValidationProvider>
//修正・Back時(検証する)
<ValidationProvider rules="required" :immediate="true" v-slot="{ errors }">
<!-- -->
</ValidationProvider>

参考

 

送信前に検証したい

フォームのタッチをする前に、submitボタンを押した時点で、入力項目の全件バリデーションを行うようにする方法です。

<ValidationObserver v-slot="{ handleSubmit }">
  <form @submit.prevent="handleSubmit(onSubmit)">
    <ValidationProvider name="E-mail" rules="required|email" v-slot="{ errors }">
      <input v-model="email" type="email">
      <span>{{ errors[0] }}</span>
    </ValidationProvider>
    <ValidationProvider name="First Name" rules="required|alpha" v-slot="{ errors }">
      <input v-model="firstName" type="text">
        <span>{{ errors[0] }}</span>
    </ValidationProvider>
    <ValidationProvider name="Last Name" rules="required|alpha" v-slot="{ errors }">
      <input v-model="lastName" type="text">
      <span>{{ errors[0] }}</span>
    </ValidationProvider>
    <button type="submit">Submit</button>
  </form>
</ValidationObserver>

data() {
  return {
    firstName: '',
    lastName: '',
    email: ''
  }
},
methods: {
  onSubmit () {
    alert('Form has been submitted!');
  }
}

 

参考

 

ボタン押下後にデータを初期化したい(エラー判定も)

this.$refs.obs.reset() を使うとエラーの判定が初期化される。
Ajaxでデータを新規登録した時に入力欄を空にするだけだと、エラーが発生してしまうので、reset() APIを使用する。

<validation-observer ref="obs" v-slot="ObserverProps">
  <validation-provider name="email" rules="required">
    <div slot-scope="ProviderProps">
      <input type="text" name="email" v-model="email">
    </div>
  </validation-provider>
  <button type="button" class="btn btn-primary" @click="submit" :disabled="ObserverProps.invalid || !ObserverProps.validated">登録</button>
</validation-observer>
new Vue({
  data:function(){
    return {
      email: '',
    }
  },
  methods:{
    submit: function() {
      this.email = '';
      this.$refs.obs.reset();
    },
  },
}).$mount('#app');

 

さいごに

Vue.js用のバリデーションコンポーネントライブラリでした。

ソースコードで目がチカチカするので食わず嫌いをしてきましたが、使ってみたら超便利でした。
今後、管理人の実務では、このバリデーションライブラリがメインになってくると思います。

 

  • この記事を書いた人

カバノキ

印刷会社のWEB部隊に所属してます。 WEB制作に携わってから、もう時期10年になります。 普段の業務では、PHPをメインにサーバーサイドの言語を扱っています。 最近のお気に入りはJavascriptです。 Vue.jsを狂喜乱舞しながら、社内に布教中です。

-UI Utilities, Validation, vue.js, ライブラリ
-, , , , ,