80
95

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue.jsを使ってて、フロントサイドのバリデーションには VeeValidate が便利

Last updated at Posted at 2017-04-08

先日、フロントサイドのバリデーションにはvalidatorjsが便利という記事を拝見し、現在作っているシステムで使ってみようとしたのですが、挫折しました。

理由としては、複雑なフロントを作ろうとしているためで、下記の要件を満たす必要がありました。

  • 1:n のデータで、ユーザーが追加できる要素がある (例: 複数メールアドレス登録)
  • ページローティング直後はバリデーションしない
    • ユーザーがインプット開始時に、 入力中の要素のみ バリデーション
  • フォームを送信する直前に 全ての要素 に対してバリデーション
    • エラーのある要素は赤くする
  • エラーのある 要素の直後 に、 「メールアドレスは必須項目です。」などというメッセージを表示
  • バリデーションのルールは一箇所にまとめたい。入力中と送信時でほぼ使いまわしたい。

そこで見つけたのが VeeValidate です。

素晴らしかったので使い方を書いておきます。

単純なバリデーション

Emailを送信するフォームがあって、下記のタイミングでバリデーションが働くようにします。

  • 入力時
  • 送信時

out.gif

Promiseでできるのが気持ちいいですね。またバリデーションのルールを <input> に置けるのが個人的には好きです。

VeeValidationSimple.vue
<template>
  <div>
    <input
       name="email"
       v-model="email"
       v-validate="'required|email'"
       :class="{'has-error': errors.has('email')}">
    <p v-if="errors.has('email')" class="alert-danger">
      {{ errors.first('email') }}
    </p>

    <button @click="register">Register</button>
  </div>
</template>

<script>
import Vue from 'vue'
import VeeValidate from 'vee-validate'

Vue.use(VeeValidate)

export default {
  data () {
    return {
      email: ''
    }
  },
  methods: {
    register () {
      this.$validator.validateAll().then((result) => {
        if (!result) {
          alert(this.errors.all())
          return
        }
        alert('Hello, ' + this.email)
      })
    }
  }
}
</script>

<style>
.alert-danger {
  color: red;
}
.has-error {
  border-color: red;
}
</style>

複数の要素に対するバリデーション

意外と簡単でした。
nameで識別しているらしいので、関連する属性値に連番を振ってあげればOKです。

VeeValidationMultiple.vue
<template>
  <div class="hello">

    <!-- 要素に連番を振る -->
    <div v-for="(account, i) in accounts">
      <input
         :name="'email' + i"
         v-model="account.email"
         v-validate="'required|email'"
         :class="{'has-error': errors.has('email' + i)}">
      <p v-if="errors.has('email' + i)" class="alert-danger">
        {{ errors.first('email' + i) }}
      </p>
    </div>

    <p>
      <button @click="addAccount">Add Account</button>
      <button @click="register">Register</button>
    </p>
  </div>
</template>

<script>
import Vue from 'vue'
import VeeValidate from 'vee-validate'

Vue.use(VeeValidate)

export default {
  data () {
    return {
      // v-forで回す要素は、オブジェクトの配列にする
      accounts: [{
        email: ''
      }]
    }
  },
  methods: {

    // 追加
    addAccount () {
      this.accounts.push({
        email: ''
      })
    },

    register () {
      this.$validator.validateAll().then((result) => {
        if (!result) {
          alert(this.errors.all())
          return
        }
        alert('Hello, ' + this.accounts)
      })
    }

  }
}
</script>

<style>
.alert-danger {
  color: red;
}
.has-error {
  border-color: red;
}
</style>

こんな感じになります。

out.gif

ちゃんと、後から追加された要素に対してもバリデーションが効いています。

参考

ドキュメントも豊富です。

今回のソースコードも貼っておきます。
https://github.com/acro5piano/vue-cli-test/blob/master/src/components/VeeValidation.vue

80
95
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
80
95

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?