Vuelidate使ってみた

今まで入力フォームのバリデーション使うのに[VeeValidate](https://baianat.github.io/vee-validate/)使ってたんですが、Nuxt v2に組み込んだ時うまい事動いてくれなかったので、これを機に[Vuelidate](https://monterail.github.io/vuelidate/)に変えてみました。

## 環境
Nuxt v2.2.0
Vuelidate v0.7.4
Vuetify v1.3.5

## Install
```bash
$ yarn install vuelidate
```

## Setup
```javascript:vuelidate.js
import Vue from 'vue'
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)
```

```javascript:nuxt.config.js
module.export = {
  plugins: ['@/plugins/vuelidate']
}
```

## Using(Example)
dataプロパティの中身を見て、自動的にVuelidateを発火させるよう`v-model="$v.{data}.$model"`にしてv-modelと紐付けてます。
自分のタイミングでバリデーションかけたい場合は、`v-model="{data}"`にして、発火したいタイミングで`this.$v.{data}.$touch()`すると良いです。

```vuejs:sign-in.vue
<template>
<v-container>
    <v-layout justify-center>
      <v-flex xs12 sm8>
        <v-toolbar color="primary" dark>
          <v-toolbar-title>ログイン</v-toolbar-title>
        </v-toolbar>

        <v-card>
          <v-container fluid>
            <v-form ref="form">
              <v-layout row wrap>
                <v-text-field type="email" v-model="$v.email.$model" label="メールアドレス" required :error-messages="emailErrors"></v-text-field>
              </v-layout>

              <v-layout row wrap>
                <v-text-field type="password" v-model="$v.password.$model" label="パスワード" required :error-messages="passwordErrors"></v-text-field>
              </v-layout>

              <v-layout row wrap justify-center>
                <v-btn block color="success" @click="signIn()">ログイン</v-btn>
              </v-layout>

            </v-form>
          </v-container>
        </v-card>

      </v-flex>
    </v-layout>
  </v-container>
</template>

<script>
import { required, email } from 'vuelidate/lib/validators'
import { validateEmail, validatePassword } from '~/utils/validations'
export default {
  head() {
    return {
      title: 'ログイン'
    }
  },

  data: () => ({
    email: '',
    password: ''
  }),

  validations: {
    email: {
      required,
      email
    },
    password: {
      required
    }
  },

  computed: {
    emailErrors() {
      return validateEmail(this.$v.email)
    },

    passwordErrors() {
      return validatePassword(this.$v.password)
    }
  },

  methods: {
    async signIn() {
      // validation発火
      this.$v.$touch()
      // validationに引っかかってるか検査
      if (this.$v.$invalid) return
      // このあとサインイン処理
    }
  }
}
</script>
```

```javascript:/utils/validations.js
export const validateEmail = validate => {
  let errors = []
  if (!validate.$dirty) return errors
  !validate.required && errors.push('メールアドレスを入力してください')
  !validate.email && errors.push('メールアドレスの形式で入力してください')
  return errors
}

export const validatePassword = validate => {
  let errors = []
  if (!validate.$dirty) return errors
  !validate.required && errors.push('パスワードを入力してください')
  return errors
}
```

Validationメッセージ共通化させたかったので`utils`作ったんですが、もっといい方法ないかなーって思ってます（知識不足）。
一応、他にもいろいろバリデーションの形式があるので、よかったら公式ドキュメント見てみてください。
[Builtin validators](https://monterail.github.io/vuelidate/#sub-builtin-validators)

## 最後に
VeeValidateのほうがGitHubのスター数とか多いですが、思ったより素直に書けたので、このまま使ってみます。
ただ、VeeValidateの`dictionary`が個人的に好きなので、Vuelidateでもあんな感じなのないかなーって思ってます。
もしVuelidate使ってて、もっといい方法知ってる人がいたら、ぜひ教えてください🙌