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

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

More than 1 year has passed since last update.

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

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

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

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

https://github.com/logaretm/vee-validate

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

単純なバリデーション

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

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
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