VueでバリデーションをVuelidateで実装してみた

##VueでバリデーションをVuelidateで実装してみた
まずはコマンドラインでnpmを使ってVuelidateをインストールします。

```
npm install vuelidate --save
```
インストールが終了したらmain.jsにVuelidateをimportしてください。

```main.js
import Vuelidate from 'vuelidate'
```
次にmain.jsに次の一文も追加に記述してください。

```main.js
Vue.use(Vuelidate);
```
これで準備が整いました。

##Vuelidateを使っていこう
使用したいコンポーネントにimportしていきます。

```
import { required } from 'vuelidate/lib/validators'
```

{}のなかに使いたいバリデータを記述しています。
※バリデータとはバリデーションを行うための機能の一種です。

これにより2つの機能が使えるようになります。

- validations コンポーネントオプション - 検証の定義
- $v 構造体 - 検証状態を保持するビューモデル内のオブジェクト

です。

validationsはVue インスタンスのコンポーネントオプションとして使用できバリデーションをかけるデータに対してどのようなバリデータをかけるかをオブジェクトで設定できます。

$vはビューモデル内で使用できるオブジェクトでこのオブジェクトにバリデーションの

結果や色々な状態の示すプロパティが入っています。このオブジェクトを見て判断をしていきます。

次に<input>要素をv-modelディレクティブでデータバインディングしたものに設定していきます。

```
 <input type="email" id="email" v-model="email">
```

```
export default {
  data () {
    return {
      email: ''
    }
  },
}
```
上記にvalidationsコンポーネントオプションを設定します。

```
export default {
  data () {
    return {
      email: ''
    }
  },
  validations: {
      email: {
        required,
      }
  }
}
```

validationsオプションを記述してその中で今回はdataオプションの所でemailと設定しているので

同じ名前のemailと記述してその中にかけたいバリデータを記述します。

いまimportしているのはrequiredだけなのでrequiredを記述します。

記述できたら次は<input>要素の方に新たに@blur="＄v.email.$touch()"と記述していきます。

```
 <input type="email" id="email" v-model="email" @blur="$v.email.$touch()">
```
@blurはVue.jsのイベントでフォーカスがなくなった時に発火します。

$v.emailはvalidationsで設定したemailの状態のプロパティが入ったオブジェクトを呼び出してます。

$v.emailのemailの部分を変更してvalidationsで設定した違うkeyを呼び出すことも可能です。

例えば

```
export default {
  data () {
    return {
      email: ''
    }
  },
  validations: {
      email2: {
        required,
      }
  }
}
```

```
 <input type="email" id="email" v-model="email" @blur="$v.email2.$touch()">
```

と変更したらemail2の状態のプロパティが入ったオブジェクトを呼び出してます。

＄touch()は＄vモデルのメッソドで$v.emailの状態のプロパティを再帰的にtrueにします。

では、次に$v.emailには状態のプロパティが入ったオブジェクトだと言いましたが

どのような状態のプロパティが入っているかをテキスト展開を追加して確認してみましょう。

```
<input type="email" id="email" v-model="email" @blur="$v.email.$touch()">
<pre>{{$v.email}}</pre>
```

<img width="222" alt="スクリーンショット 2019-04-29 12.15.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409747/cedbec57-fc14-9fd9-ccc9-70782407b402.png">

<img width="250" alt="スクリーンショット 2019-04-29 12.25.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409747/ecfe2ccc-c5b4-ad31-13be-91c6b875a063.png">

他の値も変化していますが、特に見てもらいたいのが赤線の2つです。

requiredはvalidationsオプションでemailに設定したrequiredのことを示しており

今は<input>要素に何かしら文字が入っているからtrueになっているが

何も入っていなくてフォーカスを外すとfalseになる

$modelは検証しているモデルへの参照。Vueモデルを直に参照したときと同じ値が得られます。

なのでthis.＄v.email.$modelとthis.emailは同じ値になります。

なので$modelを書き換えるとVueモデルも一緒に書き換えられます。

##Styleをつけていく

validationsでバリデーションをつけることができましたがあくまで中だけのバリデーションなので

<input>要素に入力している人は全く気づきません。

なのでこちらで$v.emailの値を参照しながらエラーになっているかどうかを示してあげないといけません。

```
.invalid {
  border: 1px solid red;
  background-color: #ffc9aa;
}
```

cssに上記を追加して<input>要素にも動的にclassを追加します。

```
<input type="email" id="email" v-model="email" @blur="$v.email.$touch()" :class="{invalid: $v.email.$error}">
```
＄v.email.$errorの値がtrueになればinvalidのclassが追加されます。

これで確認してみましょう。
<img width="250" alt="スクリーンショット 2019-04-29 13.04.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409747/498a64a9-4eb8-409b-2284-4a4c1838340c.png">

一度フォーカスをして何も入力しないでフォーカスを外すと$errorがtrueになっているため

class名が追加され<input>要素が赤く表示がされています。

これでバリデーションエラーぽくなりましたね。

次はなんでエラーになっているかをテキストで表示してあげたら親切ですね。

##テキストでエラー内容を表示する
<input>要素の下にテキストを追加していきます。

```
<input type="email" id="email" v-model="email" @blur="$v.email.$touch()" :class="{invalid: $v.email.$error}">
<p style="color:red;" v-if="$v.email.$error">メールアドレスは必須項目です。</p>
```

v-if="＄v.email.＄error"で先程のclass名のときと同じで＄v.email.$errorがtrueのときのみ

表示させるようにしています。

<img width="250" alt="スクリーンショット 2019-04-29 14.20.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409747/a8a923df-c46f-3736-f964-7fcf63b2f7bf.png">

このようにエラーしていることが分かりやすくなりました。

##その他のバリデータをご紹介

###email

有効なメールアドレスを受け入れます。

確認メールを送信せずにアドレスが本物であるかどうかを判断することは不可能であるため、

サーバー上で注意深く確認する必要があります。

###maxLength、minLength

入力された文字の長さをバリデーションします。

###numeric

数字のみを受け入れます。

###alphaNum

英数字のみを受け入れます。

などなどがあります。
まだまだバリデータはあるのでそれは[公式サイト](https://vuelidate.netlify.com/#sub-builtin-validators)をご確認ください。

##まとめ

いかかでしたでしょうか？

これであなたも簡単にバリデーションをVueで実装することができます。

是非ともやってみてください！