Nuxt.jsでVeeValidateを使う

#はじめに
Nuxt.jsで作成中のプロジェクトでバリデーションプラグインを使ったので導入から最初の設定までをまとめました。

内容は基本的に公式ドキュメントを踏襲したものです。

#バージョン
nuxt/cli: 2.15.8
vue: 2.6.12
tailwindcss: 2.2.7

#プラグインを使う
いろんなプラグインを調べた結果、Nuxt/Vueで使えるプラグインの有名どころが2つあります。

###Vuelidate
[Vuelidate | A Vue.js library.](https://vuelidate.js.org/)

###VeeValidate ←今回使うもの
[VeeValidate](https://vee-validate.logaretm.com/v3)

VeeValidateの方がバージョンが安定しているので今回はそちらを使うことにしました。

#インストール
:::note warn
公式のヘッダーにも警告ができますが、Vue2とVue3ではVeeValidateのバージョンが異なるのでご注意ください。
:::

```sh
# npmの場合
npm install vee-validate --save

# yarnの場合
yarn add vee-validate
```

#基本的な形
バリデーションをかけるinputタグを`ValidationProvider`タグでくくる。エラー表示のために記載されているv-slotの中身の値をslot propsと呼びます。


```vue
<ValidationProvider rules="positive" v-slot="{ errors }">
  <input v-model="email" type="text" />
  <span>{{ errors[0] }}</span>
</ValidationProvider>
```

#VeeValidateを使う
同じファイル内のscriptタグ内でコンポーネントをimportします。

```jsx
import { ValidationProvider } from 'vee-validate';

export default {
  components: {
    ValidationProvider
  }
};
```

<br>
vee-validationにはデフォルトのバリデーションが設定されていないため自分で追加していくことになる。ルールの追加は下記のように行います。

```jsx
import { extend } from 'vee-validate';

extend('positive', value => {
  return value >= 0;
});
```

<br>
バリデーションを付与したいフォームにrulesを追加します。
これで完成。ちゃんとバリデーションが機能しています。

```jsx
<ValidationProvider rules="positive" v-slot="{ errors }">
  <input v-model="value" type="text">
  <span>{{ errors[0] }}</span>
</ValidationProvider>
```

<br>
画面はこんな感じ。見にくいですが。
値が0以上なら正常に入力可能です。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230656/c0442f92-bc8a-928a-5594-c33eaab74881.png)


値が0以下でバリデーションが作動。エラーメッセージがでます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230656/6d82ce7d-19bd-9d09-89a8-d57ed2ae7ec9.png)

#バリデーションを複数設定する
バリデーションはこのように複数設定もできます。
この場合はoddというバリデーションを別途script内に作成して適用しています。

```jsx
<ValidationProvider rules="positive|odd" v-slot="{ errors }">
  <input v-model="value" type="number">
  <span>{{ errors[0] }}</span>
</ValidationProvider>
```

#エラーメッセージの変更をしたい場合
エラーメッセージを変更したい場合はreturnで渡すことができます。
returnの中を変更することでエラーメッセージを自由に変更することができます。


```jsx
import { extend } from 'vee-validate';

extend('positive', value => {
  if (value >= 0) {
    return true;
  }

  return 'This field must be a positive number';
});
```

# エラー文に動的な文字を使いたい場合
固定されたエラー文ではなく動的に文字を変更したい場合、下記で実現できます。

<br>
エラー文の中に`{_field_}`を記載。

```jsx
extend('positive', value => {
  if (value >= 0) {
    return true;
  }

  return 'The {_field_} field must be a positive number';
});
```

`{_field_}`に入る値をそれぞれのタグのnameで指定する。

```vue
<ValidationProvider name="age" rules="positive" v-slot="{ errors }">
  <input v-model="value" type="text">
  <span>{{ errors[0] }}</span>
</ValidationProvider>
```

#バリデーションにオブジェクトの引数を取りたい場合
下記のようにオブジェクトの引数を取ることもできます。

```jsx
<ValidationProvider rules="minmax:3,8" v-slot="{ errors }">
  <input v-model="value" type="text">
  <span>{{ errors[0] }}</span>
</ValidationProvider>

extend('minmax', {
  validate(value, { min, max }) {
    return value.length >= min && value.length <= max;
  },
  params: ['min', 'max']
});
```

#引数を変数としてエラー文に組み込みたい場合

引数をエラー文に挿入したい場合は下記で実現できます。

`{}のみでアンダースコアをつけない点に注意。`

```jsx
extend('minmax', {
  validate(value, { min, max }) {
    return value.length >= min && value.length <= max;
  },
  params: ['min', 'max'],
  message: 'The {_field_} field must have at least {min} characters and {max} characters at most'
});
```