Help us understand the problem. What is going on with this article?

VeeValidate を使って、vue.jsで簡単にバリデートしてみた

現在、vue.jsを使って色々と作っているのですが、フォームでのバリデーションで便利なVeeValidateというライブラリを使ってみました。

環境情報

  • Vue.js 2.5.13
  • VeeValidate 1.0.0

事前準備

現在、Rails + webpacker + Vue.jsで開発を行なっています。
そのため、yarnを使ってVeeValidateを導入しました。
yarn add vee-validate

そしたら、VeeValidateを読み込む!

app.js
import VeeValidate, { Validator } from 'vee-validate'

これで、事前準備は完了!

基本的な使い方

VeeValidateはhtmlタグの中に、決まり文句を書くだけで、バリデートの設定をしてくれます。

form.vue
<div class="form-group">
   <label for="form_title">タイトル</label>
   <input type="text" name="app[title]" class="form-control"
          v-model="app.title"
          data-vv-as="タイトル"
          v-validate="'required|max:255'"
         :class="{'input': true, 'form-danger': 
         errors.has('app[title]') }"
   />
   <div class="form-control-feedback" v-show="errors.has('app[title]')">
     <p class="alert alert-danger">{{ errors.first('app[title]') }}</p>
   </div>
</div>

雛形はこんな感じになります。

バリデートルールの指定

基本的に、inputタグの中に色々書き込むだけです。
v-validateの中にバリデートのルールを書き込みます。

ルール 意味
required 必須
max 最大文字数
numeric 半角数値のみ
email メールアドレス形式

よく使うのは、この辺りでしょうか。v-validate = "required"と書き込むだけで、必須項目としてルールを追加できます。複数の条件を指定したい場合は|で区切ればOK!

エラーメッセージの表示

指定したルールを満たさない場合は、errors.has('inputのname')の中のフラグがtrueとなります。なので、それを活用して、v-show="errors.has('app[title]')"とすれば、
値が入ってないときは、メッセージを非表示、空の時メッセージ表示となります。
また、エラーメッセージはerros.first('inputのname')にあるので、
{{ errors.first('app[title]') }}でエラーメッセージが表示されます。

ただ、このままでは、エラーメッセージが
The app[title] field is required.
と表示されてしまうので、エラーメッセージを日本語に変えたいです。

エラーメッセージを日本語化する

app.js
// 日本語ファイルを読み込み
import ja from 'vee-validate/dist/locale/ja'

// vee-validateの日本語
Validator.localize('ja', ja);
Vue.use(VeeValidate, { locale: ja });

上記のように書き込めば日本語化されます。
app[title]は必須項目です
まだ、field名がキモいのでinputタグに直接field名を記述します。
data-vv-as="タイトル"と書き込めば、OK

title.gif

こんな感じでスマートに動きます。

特殊なバリデート

よく使うと思うのですが、フォーム中で、ある条件の中だけ必須項目にしたいみたいなこともあると思います。

app.vue
<div class="form-group">
  <label>投票締切</label>
  <div class="form-check">
      <label for="is_deadline_true" class="form-check-label">設定する</label>
      <input type="radio" id="is_deadline_true" name="app[is_deadline]" value="1"
             v-model="app.is_deadline"
             v-on:change="checkDeadline"
      >
      <label for="is_deadline_false" class="form-check-label">設定しない</label>
      <input id="is_deadline_false" type="radio" name="app[is_deadline]" value="0"
             v-model="app.is_deadline"
             v-on:change="checkDeadline"
      >
  </div>
</div>
<div class="form-group" v-show="deadline_show">
  <label for="deadline_at">投票締切日時</label>
  <input id="deadline_at" type="date" name="app[deadline_at]" 
        class="form-control"
         v-model="app.deadline_at"
         data-vv-as="投票締切日時"
         v-validate ="'date_format:YYYY-MM-DD'"
  />
</div>

今回は、投票締切というラジオボタンで、設定するを選択されている時のみ、
投票締切日時を必須にするという処理を行います。
htmlは先ほどと特に変化はないのですが、radioボタンの値が切り替わった時に動く
checkDeadlineというメソッドを作りました。

app.vue
checkDeadline: function () {
// 締切日時を設定していない場合、締切日時の値を空にする
    if(this.app.is_deadline == 0) {
        // 任意項目にする
        this.$validator.detach('app[deadline_at]');
    } else {
        // 必須項目にする
        this.$validator.attach({
            name: 'app[deadline_at]',
            alias: '投票締切日時',
            rules: 'required',
            scope: this.app.deadline_at
        });
    }
}

attachを使えば、ある条件下の時に、バリデートの条件を追加することができます。
バリデート条件を外したい時は、detatchを使用します。
ちなみに、最初scopeを指定しなかったために、app[deadline_at]の値が入力されていても、
バリデートに引っかかるという沼にハマりました。scopeで、ちゃんとどの値を参照しないといけないのか指定してあげる必要がありそうです。

フォームの送信ボタンを押したら、バリデートが走る

フォームの送信ボタンを押した時に、バリデートが走らないとそもそも意味ないですね。
なので、送信ボタンを押下した時に、バリデートが走るメソッドを準備します

app.vue
<button type="button" class="btn btn-primary" v-on:click="postApp">
作成する
</button>
app.vue
postApp: function () {
  // バリデートの判定
  this.$validator.validateAll().then((result) => {
      if (result) {
         //エラーがなかった時の処理を下に記述
      }
  });
},

上記のメソッドだけで、エラーがあったら、エラーメッセージが自動で表示されるようになります。

Mar-21-2018 10-51-49.gif

終わり

こんな感じで、簡単にバリデート処理を書けます。
少ない記述で書けるので、vue.jsを使う時はVeeValidateを使うと
かなり捗るのではないでしょうか?

参照
VeeValidateドキュメント
VeeValidateを使ってみる

youdie
WEBエンジニアとして働いています。社会人4年目です。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした