WebDesign Dackel

Vue.jsでバリデーション、vue-validatorを使ってみる

Vue.jsでバリデーション、vue-validatorを使ってみる

Hatena0
Google+0
Pocket0
Feedly0

久しぶりにVue.jsの記事です。
前回触った時にはバリデーション用のプラグインであるvue-validatorが、0.11.Xに対応していなかったこともあり使用するのを見送っていました。
最近になってGitHubのリポジトリを見てみると、なんとありがたいことに0.11.2に対応しているとのことだったので早速触ってみました。

ちなみに今回使ったVue.jsのバージョンはv0.11.5でしたが問題無く動作しました!

サンプル

インストールと、基本的な使い方はあとで紹介するとしてまずは動作するサンプルです。

サンプル

こんな感じのバリデーションがVue.js上で簡単に実装できました。素晴らしいです。
サンプルのコードは、記事の下のほうにまとめて記載しました。

では早速使い方を見ていきます。

インストール

プラグインのリポジトリを見ると、次の方法でインストールできるよ!とあります。

  • browserify (npm)
  • bower
  • component
  • duo

今回サンプルで使ったのはnpmを使った方法です。

gulp+webpack(npm)で使う

webpackgulpから使う構成にしてみました。
使ったプラグインはgulp-webpackです。

gulp-webpack

素のwebpackでも勿論OKですが、gulpっぽい使い方ができるので今回はこちらを採用です。

まずはvuevue-validatorをインストールします。
(--save-devオプションは必要に応じて指定)

$ npm install vue vue-validator --save-dev

下記のようなタスクを用意しました。

gulp.task "webpack", ->
  gulp.src "src/app.js"
  .pipe $.webpack {
    output: {
      filename: "app.js"
    }
    resolve: {
      root: [path.join(__dirname, "node_modules")]
    }
    extensions: ["", ".js"]
  }
  .pipe gulp.dest "dist"

これで下記コマンドを実行すると、./dist/app.jsが生成されます。

$ gulp webpack

そしてメインとなるapp.jsで下記を記載すれば準備完了です。

var Vue = require("vue");
var validator = require("vue-validator");

Vue.use(validator);

scriptタグで使う

いちいちこんな面倒くさい構成は嫌だ!という方は、いつも通りHTMLにscriptタグで書くことも出来ます。

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/vue-validator.js"></script>

必要なJSを読み込んだら、app.jsには下記のように記載します。

Vue.use(window["vue-validator"]);

こちらの方法でもvue-validatorを使うことが出来ます。

基本的な使い方

vue-validatorを使うことで、v-validateディレクティブが有効になります。
有効になったディレクティブに対して、カンマ区切りで検証ルールを加えていくとvalidationオブジェクトに、それぞれのモデル毎に検証結果を保持してくれます。
下記のようにしてアクセスすることが出来ます。

// validation.モデル名.検証ルール
validation.model.validator

検証結果と似ていますが、少し違うdirtyというプロパティ?も生成されていて、これは初期値から変更があったかという判定をしてくれています。

また、便利なことに全てのバリデーションが通っているかという判定も、自動的に行なってくれています。
全ての検証ルールをクリアしていればvalid、一つでもエラーがあればinvalidで判定可能です。

実際、必須項目を表すrequiredで使ってみるとこんな感じになります。

<form id="app-form">
  <input type="text" v-modal="login" v-validate="required"><br />
  <p v-if="validation.login.required">ログインIDは必須です!</p>

  <p v-if="invalid">入力内容にエラーがあります!</p>
  <p v-if="valid"><input type="submit" value="送信する"></p>
</form>
var Vue = require("vue");
var validator = require("vue-validator");
Vue.use(validator);

var appForm = new Vue({
  el: "#app-form",
  data: {
    login: ""
  }
});

validation.login.requiredloginモデルが入力されているか、という検証結果が入っているので、その値を使ってエラーメッセージを表示しています。
基本的な使い方はこんな具合ですので、他にもいくつか用意されている検証ルールを見ていきたいと思います。

デフォルトで使用できる検証ルール

required

単純に入力があるか判定してくれます。

<input type="text" v-moddel="name" v-validate="required"><br />
<p v-if="validation.name.required">ユーザ名が未入力です!</p>

pattern

正規表現で許可するパターンを指定する事ができます。

<input type="text" v-moddel="login" v-validate="pattern: /^[0-9a-zA-Z]*$/"><br />
<p v-if="validation.login.pattern">半角英数字のみ使用できます</p>

minLength

最低限必要な文字数を指定できます。

<input type="text" v-moddel="password" v-validate="minLength: 4"><br />
<p v-if="validation.password.minLength">4文字以上入力して!</p>

maxLength

最大の文字数を指定できます。

<input type="text" v-moddel="password" v-validate="maxLength: 12"><br />
<p v-if="validation.password.minLength">12文字以内にしてください</p>

min

minLengthは文字数だったのに対して、こちらは数値比較した際の最小値を指定できます。

<input type="text" v-moddel="age" v-validate="min: 18"><br />
<p v-if="validation.age.min">18歳未満は立ち入り禁止です!</p>

max

minと同様、数値比較した際の最大値を指定できます。

<input type="text" v-moddel="age" v-validate="max: 65"><br />
<p v-if="validation.age.max">65歳以下の方のみ対象となります</p>

検証ルールの追加

validator.validatesにルールを追加することで、カスタムバリデータを使用することができます。
メールアドレスの形式チェックと、値のマッチングを追加してみます。

var appForm = new Vue({
  el: "#app-form",
  data: {
    email: "",
    emailConfirm: ""
  },

  // カスタムバリデータを追加
  validator: {
    validates: {
      email: function(val){
        return /^(([^<>()[].,;:s@"]+(.[^<>()[].,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/.test(val);
      },
      match: function(val, model){
        return val === this[model];
      }
    }
  }
});
<form id="app-form">
  メールアドレス: <input type="email" v-model="email" v-validate="email"><br />
  メールアドレス (確認): <input type="email" v-model="emailConfirm" v-validate="match:email">
</form>

matchには:区切りで検証先のモデル名を指定するような仕組みにしてみました。

使いそうなオプション

名前空間の変更

自動で割り振られるvaliddirtyなどの値の名前を任意に変更する事ができるみたいです。
既にこの変数名を使っちゃってるよー!という場合に便利そうです。

var appForm = new Vue({
  ...
  validator: {
    namespace: {
      validation: "appValidation", 
      valid: "appValid", 
      invalid: "appInvalid", 
      dirty: "appDirty"
    }
  }
  ...
});

サンプルコード

一部余計な箇所は省いてしまっていますが、だいたいこんな感じです。

HTML

<div id="app">
  <dl>
    <dt>ユーザ名</dt>
    <dd>
      <input type="text" v-model="name" v-validate="required, maxLength:12">
      <p v-if="validation.name.required" class="error">ユーザ名は必須です</p>
      <p v-if="validation.name.maxLength" class="error">ユーザ名が長過ぎます</p>
    </dd>
    <dt>ユーザID</dt>
    <dd>
      <input type="text" v-model="login" v-validate="required, maxLength:12, pattern:/^[0-9a-zA-Z-_]*$/">
      <p v-if="validation.login.required" class="error">ユーザIDは必須です</p>
      <p v-if="validation.login.maxLength" class="error">ユーザIDが長過ぎます</p>
      <p v-if="validation.login.pattern" class="error">ユーザIDは半角英数字のみ使用可能です</p>
    </dd>
    <dt>メールアドレス</dt>
    <dd>
      <input type="email" v-model="email" v-validate="required, email">
      <p v-if="validation.email.required" class="error">メールアドレスは必須です</p>
      <p v-if="validation.email.email && validation.email.dirty" class="error">メールアドレスの形式が不正です!</p>
    </dd>
    <dt>メールアドレス 確認</dt>
    <dd>
      <input type="email" v-model="emailConfirm" v-validate="required, match:email">
      <p v-if="validation.emailConfirm.match" class="error">メールアドレスが一致しません</p>
    </dd>
  </dl>

  <p v-if="invalid">入力内容にエラーがあります</p>
  <p v-if="valid"><input type="submit" value="登録する"></p>
</div>

<script type="text/javascript" src="dist/app.js"></script>

JavaScript

var Vue = require("vue");
var validator = require("vue-validator");
Vue.use(validator);

var app = new Vue({
  el: "#app",
  data: {
    name: "",
    login: "",
    zip: "",
    email: "",
    emailConfirm: ""
  },
  validator: {
    validates: {
      email: function(val){
        return /^(([^<>()[].,;:s@"]+(.[^<>()[].,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/.test(val);
      },
      match: function(val, model){
        return val === this[model];
      }
    }
  }
});

参考サイト

詳しい使い方についてはvue-vadalitorのリポジトリをご確認ください。

Vue.js
vue-validator