Vue.JSでフォームのvalidationを行う


vue.jsでvalidation付きフォームを作った。

基本機能

・フォームが正しく入力されているかリアルタイムで出る
・送信ボタンを押した時、全フォームが正しく入力されているか判定して処理を分ける

ようにしている。
今はフォームが空か否かで判定しているが、評価項目(文字数制限など)は比較的簡単に追加できる。

実装方法

validationを行うにはvue-validatorというライブラリを使うことも可能だが、簡単なvalidationだけではわざわざ使うほどでもない。

公式にあるfirebase+vuejsでのexampleを参考に実装した。

今回のソースコード:github

validationを作る

今回は
* title
* description
* date
* location
からなるフォームを作る。

入力された情報はnewEventに保持する。
それぞれの項目に対し、booleanをもつvalidationを作成する。

data: {
      newEvent: {
        title: '',
        description: '',
        date: '',
        location: ''
      },
      validation: {
        title: false,
        description: false,
        date: false,
        location: false
      }
    },

validationを行うfilterを作る

HTMLソース内でそれぞれの入力にたいして評価を行うfilterを作成する。
今回は空白か否かのみを作成しているが、ここに評価を追加すれば他の評価方法を追加できる。
例えば公式のexampleではemailアドレスになっているか正規表現でチェックをしているし、文字数制限を課すこともできる。

 filters: {
      titleValidator: {
        write: function (val) {
          this.validation.title = !!val
          return val
        }
      },
      descriptionValidator: {
        write: function (val) {
          this.validation.description = !!val
          return val
        }
      },
      dateValidator: {
        write: function (val) {
          this.validation.date = !!val
          return val
        }
      },
      locationValidator: {
        write: function (val) {
          this.validation.location = !!val
          return val
        }
      }
    },

ちなみに、ソースコード内の

this.validation.title

などは先ほど宣言したdataの中のvalidationの要素である。
filterで評価した結果がvalidationの要素に格納される。

HTMLソース内で入力項目をfilterに通す

<form id="form" v-on="submit:addEvent">
    <p>title:<input v-model="newEvent.title | titleValidator"></p>
    <p>description:<input v-model="newEvent.description | descriptionValidator"></p>
    <p>data:<input v-model="newEvent.date | dateValidator"></p>
    <p>location:<input v-model="newEvent.location | locationValidator"></p>
    <input type="submit" value="Add event">
  </form>

v-modelは編集可能な要素に対して双方向データバインディングを提供する(参考

v-model="newEvent.title | titleValidator"

でdataで宣言したnewEvent.titleに対し、filterで作成したtitleValidatorに通す。
titleValidatorの評価結果はdataのvalidation.titleに随時格納される。

エラーであれば表示する

v-showにbooleanを渡すと、trueの場合のみ表示できるようにできる。
ここに書く要素のvalidationを渡すことで、エラーの場合のみ表示するようにできる。

  <ul class="errors">
    <li v-show="!validation.title">title cannot be empty.</li>
    <li v-show="!validation.description">description cannot be empty.</li>
    <li v-show="!validation.date">date cannot be empty.</li>
    <li v-show="!validation.location">location cannot be empty.</li>
  </ul>

エラーの有無を常時監視する

入力フォームのvalidationの中に、一つでもfalseがあるか確認するようにする。
常時計算が行われるcomputedにて、booleanを返すisValidを用意しておく。

computed: {
      isValid: function () {
        var valid = true
        for (var key in this.validation) {
          if (!this.validation[key]) {
            valid = false
          }
        }
        return valid
      }
    },

validationの全ての要素を確認していって、一つでもfalseが見つかったらをfalseを返す。

  methods: {
      addEvent: function (e) {
        e.preventDefault()
        if (this.isValid) {
          console.log("success")
        }else{
          console.log("need edit")
        }
      },
    }

addボタンが押されたらisValidの値に基づき処理を変える

<form id="form" v-on="submit:addEvent">
    <!--中略-->
    <input type="submit" value="Add event">
  </form>

formにてsubmitが押されたら、addEventメソッドが実行される。

    methods: {
      addEvent: function (e) {
        e.preventDefault()
        if (this.isValid) {
          console.log("success")
        }else{
          console.log("need edit")
        }
      },
    }

addEventが実行されたら、if文でisValidを評価して処理を分ける。

Vue.js参考書籍

Vue.js入門 基礎から実践アプリケーション開発まで