Nuxt.js

VeeValidate3.X + Nuxt.js + Vuetify でバリデーション実装

VeeValidate公式によると、過去 Nuxt.js で VeeValidate を使うにはいくつか面倒な設定がありましたが、VeeValidate3系になって、気にしなくて良くなったようです。

https://logaretm.github.io/vee-validate/examples/nuxt.html

今回バリデーション処理を実装する必要があったので、VeeValidate3.X系をNuxt.jsに組み込んでみました。

なお、今回はNuxt.js, Vuetify は既にセットアップ済みという前提です。

Vee-Validateの設定

Vee-Validate のインストール

ここら辺は言わずもがなですね。 よしなにインストールしてください。

# install with npm
npm install vee-validate

# install with yarn
yarn add vee-validate

plugins/ ディレクトリに追記

まずはサンプル通りに pluginsディレクトリ配下にファイルを作成します。

:~/plugins/vee-validate.js

import { extend } from "vee-validate";
import { required } from "vee-validate/dist/rules";

// install the 'required' rule.
extend("required", {
…required,
message: "This field is required"
});

nuxt.jsのプラグインは、Vueのインスタンスが作成される前に、実行する処理を追記することができます。Vueインスタンスに注入したい機能があったりしたら使う場所ですね。

https://ja.nuxtjs.org/guide/plugins

その後、作成したプラグインを読み込んでもらうため、nuxt.config.jspluginsプロパティに追記しましょう。
また、トランスパイルができなくてエラーが出ることがあるので、例外処理も追記しておきましょう。

nuxt.config.js

/*
** Plugins to load before mounting the App
*/
plugins: [
// 下記を追記
'~/plugins/vee-validate'
],
…
build: {
// 追記開始
transpile: [
'vee-validate/dist/rules'
],
// 追記終了
},

これで各ページのVueインスタンスを生成するときにvee-validateが呼び出されるようになりました!

余談: Vee-Validateの仕組み

ここで、Vee-Validateの基本的な使い方についてもまとめておきましょう。

まず最初に、ValidationProviderというコンポーネントを利用します。

https://logaretm.github.io/vee-validate/guide/validation-provider.html#scoped-slot-data

<ValidataionProvider>タグで<input>タグを囲います。

公式のサンプルを引用します。

<template>
  <ValidationProvider rules="required" v-slot="{ errors }">
    <input v-model="value" type="text" />
    <span id="error">{{ errors[0] }}</span>
  </ValidationProvider>
</template>

<script>
import { ValidationProvider } from 'vee-validate';

export default {
  components: {
    ValidationProvider
  }
};
</script>

でも、ValidationProviderだけでは、フォーム自体の状態(disabledなのか、readonlyなのか…など)を判断することができません。

そこで登場するのが、ValidationObserverです。

https://logaretm.github.io/vee-validate/guide/validation-observer.html#scoped-slot-data

なので、まずは

<ValidationObserver>
  <ValidationProvider>
    <input>
  </ValidationProvider>
  ...
  <ValidationProvider>
    <input>
  </ValidationProvider>
</ValidationObserver>

という使い方をする、ということに慣れておきましょう。

後は validation context と呼ばれるスロットのデータ(一つ前のサンプルに記述されている v-slot="{ errors }" の部分ですね)を渡すことでエラーメッセージなどをやりとりしていますが、細かい話は別の記事に譲ります!

コンポーネントを作る

ここまできたら後一息です!こんなコンポーネントを作ってみましょう

<template>
 <ValidationObserver ref="obs" v-slot="{ invalid, validated, passes, validate }">
    <v-form>
      <ValidationProvider
        v-slot="{ errors, valid }"
        rules="required"
      >
        <v-text-field
          v-model="email"
          :error-messages="errors"
          :success="valid"
          label="test"
          required
          filled
        />
      </ValidationProvider>
    </v-form>
 </ValidationObserver>
</template>
<script>
import { ValidationObserver, ValidationProvider } from 'vee-validate'

export default {
  components: {
    ValidationObserver,
    ValidationProvider
  }
}
</script>

こんな風な表示になっていたら成功です!

alt

いろんなルールを適用してみる

あとは、デフォルトでVee-Validateが用意してくれているルールを活用するだけです!

  1. plugins/vee-validate.jsにルールを追記する
  2. ValidationProvider にルールを追記する

の2ステップだけです!

例えば、max10文字制限をかけたいなら、

import { extend } from 'vee-validate'
- import { required } from 'vee-validate/dist/rules'
+ import { required, max } from 'vee-validate/dist/rules'

// install the 'required' rule.
extend('required', {
  ...required,
  message: 'This field is required'
})

+ extend('max', {
+   ...max,
+   message: 'This field must be {length} characters or less'
+ })

として、

<ValidationProvider
  v-slot="{ errors, valid }"
-  rules="required"
+  rules="required|max:10"
>

と追記するだけです!

alt

他にルールのプリセットがたくさん用意されているので、それらを活用することで効率的にルールづけができそうですね!

ちなみに、公式のサンプルではコンポーネントを用意していました。

https://codesandbox.io/s/veevalidate-components-vuetify-pij6w

確かに、コンポーネント化してしまった方が使い勝手が良さそうですね!

以上、大雑把な流れでした!

ABOUT ME
どんぶラッコ
ECコンサルタント、システムエンジニアを経て、quintet株式会社CTOに就任。普段はNuxt.jsやLaravelを使用しています。

\面白いと思ったら/

記事のシェア & Twitter のフォロー をお願いします!

@proglearn
RELATED POST

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です