PIYO - Tech & Life -

Vue.jsでのフォームバリデーションにVeeValidateを使ってみる

Vue JS

ちょこちょこVue.jsを使ってるんですが、まだ手に馴染みません。まだまだ馴染まない理由の1つにフォームがあります。

Railsをメインに使う生活をしているので、form_forがないとフォームが書けません。というか、simple_form gemばかり使っているのでさらになまっていて、たとえばbootstrapのフォームがどんな構造なのかを忘れているので、すごく手間がかかってしまいます。

さて、フォームを組み立てたら次はValidationしたくなります。昔ながらなRailsアプリケーションではフォームの内容をいったんサーバーに送って、サーバーサイドでバリデーションを書けます。

せっかくVue.js使うならクライアントサイドでもそれなりにやってしまったほうが良いですよね(ですよね?)。

VeeValidateというVue.js用のバリデーションライブラリを見つけたので試しました。

GitHub - logaretm/vee-validate: ✅ Form Validation for Vue.js
✅ Form Validation for Vue.js. Contribute to logaretm/vee-validate development by creating an account on GitHub.

VeeValidate用サンプルアプリ

問い合わせフォームっぽいものを作りました。

  • メールアドレス
  • タイトル
  • 本文

を入れてもらうフォームで、全項目必須、メールはフォーマットまで確認するということにしました。

HTML

<div id="app">
  <form action="" @submit.prevent="validate">
    <div class="form-group">
      <label for="">メールアドレス</label>
      <input name="email" type="text" class="form-control" v-validate="'required|email'" />
      <span class="text-danger">{{ errors.first('email') }}</span>
    </div>
    <div class="form-group">
      <label for="">タイトル</label>
      <input name="title" type="text" class="form-control" v-validate="'required'" />
      <span class="text-danger">{{ errors.first('title') }}</span>
    </div>
    <div class="form-group">
      <label for="">本文</label>
      <textarea rows="5" class="form-control" name="body" v-validate="'required'">
      </textarea>
      <span class="text-danger">{{ errors.first('body') }}</span>
    </div>
    <button type="submit" class="btn btn-primary">送信</button>
  </form>
</div>

見た目は↓↓な感じね。

JavaScript

JavaScriptはあまり書くことがありません。

  • VeeValidate自体の登録
  • Vueインスタンスの生成
  • バリデーション処理

うまくいったときだけalertが表示されます。実際のアプリケーションではサーバーにPOSTするなど必要な処理を実行することになります。

Vue.use(VeeValidate);

new Vue({
  el: '#app',
  methods: {
    validate() {
      this.$validator.validateAll()
       .then((result) => {
          if (result) {
            alert('valid!');
          }
      });
    }
  }
});

VeeValidateの使い方

VeeValidateで重要なのことはこの2行を見れば大体わかると言えそうです。

<input name="email" type="text" class="form-control" v-validate="'required|email'" />
<span class="text-danger">{{ errors.first('email') }}</span>

1行目のname=v-validate=、2行目のerrors.first('email')が重要です。

name

namedata-vv-nameがないと警告が出ます。

"[vee-validate] A field is missing a 'name' or 'data-vv-name' attribute"

後述するエラー情報などに使われるからだと考えられます。

v-validate

こちらはバリデーション条件を指定する属性で、文字列やオブジェクトを渡すことができるようです。

必須項目には'required'、必須かつメールアドレスのフォーマットチェックには'required|email'のように複数の条件を結合して使えそうです。

ルールの一覧はこちらのドキュメントに。

かなり豊富なので大抵のことは簡単に指定できそう。

さきほどの例では、'required''required|email'を使っています。

エラー表示

errors.first('email')には、name="email"なinputにバリデーションエラーがある場合に、エラーメッセージが入っています。

<span class="text-danger">{{ errors.first('email') }}</span>

として表示するようにしておくと、エラーがあるときだけメッセージが表示されます。

エラーメッセージの日本語化やフォームの見た目調整など気になるところはありますが、ひとまずこれでバリデーションできたと言えそうなところまで来ました。

コード全体

今回のコード全体です。