Nuxt.jsでバリデーションするためにVeeValidateを使う
はじめに
Nuxt.jsでフォームのバリデーションをするためにVeeValidateを使ったので設定手順と簡単な使い方をまとめます。なお、VeeValidateはバージョン2系と最新の3系では大きく変わっています。この記事では、最新のバージョン3系についてまとめます。
前提と環境
Nuxt.jsとVeeValidateのバージョンは以下の通りとします。
- Nuxt.js : 2.9.2
- vee-validate: 3.0.5
VeeValidateの公式ドキュメントは以下です。
VeeValidateをインストールする
npmでインストールします。
$ npm install vee-validate --save
VeeValidate用のプラグインファイルを作成する
VeeValidateの設定をまとめておくプラグインファイルを作成します。Nuxt.jsアプリのルートディレクトリにplugins
ディレクトリがあるので、そこにvee-validate.js
というファイル名で以下の内容を記述します。ValidationProvider
、ValidationObserver
の使い方は後述します。
import Vue from 'vue'
import { ValidationProvider, ValidationObserver, localize, extend } from 'vee-validate' // 使用する機能
import ja from 'vee-validate/dist/locale/ja.json' // エラーメッセージの日本語化用
import { required, max, email } from 'vee-validate/dist/rules' // 使用するバリデーションルール
// VeeValidateがデフォルトで用意している各ルールを使用するよう指定
extend('required', required) // 必須項目のバリデーション
extend('email', email) // emailのバリデーション
extend('max', max) // 最大文字数のバリデーション
Vue.component('ValidationProvider', ValidationProvider)
Vue.component('ValidationObserver', ValidationObserver)
localize('ja', ja)
もし、VeeValidateが用意している全てのルールを使用したい場合は、以下のようにすることで全てのルールをインポートすることができます。
import Vue from 'vue'
import { ValidationProvider, ValidationObserver, localize, extend } from 'vee-validate' // 使用する機能
import ja from 'vee-validate/dist/locale/ja.json' // エラーメッセージの日本語化用
import * as rules from 'vee-validate/dist/rules' // 全てのバリデーションルール
// forループで全てのバリデーションルールをextendで登録する
for (let rule in rules) {
extend(rule, rules[rule])
}
Vue.component('ValidationProvider', ValidationProvider)
Vue.component('ValidationObserver', ValidationObserver)
localize('ja', ja)
VeeValidateで使用できるルール一覧は、以下の公式ドキュメントに全て記載されています。十分種類が多いです。
VeeValidate offers common validators that will cover most apps needs:
nuxt.config.jsに設定を追記する
作成したvee-validate.js
を読み込むために以下の記述をnuxt.config.js
に加えます。
module.exports = {
mode: 'universal',
// ...省略...
/*
** Plugins to load before mounting the App
*/
plugins: [
// 以下を追記
{ src: '@/plugins/vee-validate'}
],
// ...省略...
build: {
// 以下を追記
transpile: [
"vee-validate/dist/rules"
],
/*
** You can extend webpack config here
*/
extend(config, ctx) {}
}
上記のplugins
にて、作成したvee-validate.js
を指定しています。また、build
部分には、transplie
という項目を追加していますが、これは各自のNuxt.jsの設定によって必要になる場合があります。もしUmexpected token export
というエラーが自身のNuxt.jsで表示される場合は、この記述を追記してみてください。
VeeValidateを使ってバリデーションを行う
VeeValidateでは、ValidationProvider
というコンポーネントを使って任意のフォームにバリデーションを実装することができます。例えば、以下は適当な例となりますが、フォームの項目を入力必須としたい場合には以下のようになります。
<template>
<section class="section">
<div class="columns is-mobile">
<div class="field">
<label class="label">テキストフォーム</label>
<div class="control">
<validation-provider v-slot="{ errors }" rules="required" name="テキスト項目">
<input v-model="textValue" class="input" type="text" placeholder="Text input" />
<p v-show="errors.length" class="help is-danger">
{{ errors[0] }}
</p>
</validation-provider>
</div>
</div>
</div>
</section>
</template>
<script>
import Card from '~/components/Card'
export default {
name: 'HomePage',
data () {
return {
textValue: ''
}
}
}
</script>
上記の例では、テキストフィールドに入力内容がない場合は以下のように必須項目である旨のメッセージが表示されます。
Nuxt.jsでVeeValidateを使用する際の注意点として、ValidationProvider
をコンポーネントととして使う場合、ケバブケース(ハイフン区切り)で使います。すなわち、
となります。ただ、これは各自の設定によります。VeeValidateの公式ドキュメントでは、
というようにキャメルケースになっているのでそのまま貼り付けてもエラーとなる場合があります。
なお、上記の例では、フォームの送信ボタンに相当するものがなく実用的でないため、バリデーションが通らないと送信ボタンを押せないようにするための例を以降に載せます。
全てのバリデーションが通るまで送信ボタンを無効化する例
実際のフォームでは、複数の入力項目が存在し、各項目に対してバリデーションをかけたい場合が多いと思います。ここでは、ValidationObserver
を使って複数項目に対するバリデーションチェックを行い、さらに全てのバリデーションが通るまでは送信ボタンを無効化する例を載せます。前述したform.vue
を以下の様にします。
<template>
<section class="section">
<div class="columns is-mobile">
<validation-observer v-slot="{ invalid }">
<div class="field">
<label class="label">お名前</label>
<div class="control">
<text-field-with-validation v-model="textValue" rules="required" fieldname="お名前" />
</div>
</div>
<div class="field">
<label class="label">メールアドレス</label>
<div class="control">
<text-field-with-validation v-model="emailValue" rules="required|email" fieldname="メールアドレス" />
</div>
</div>
<div class="field">
<div class="control">
<button class="button is-link" :disabled="invalid">送信する</button>
<p v-show="invalid" class="help is-danger">
全ての必須項目を入力すると「新規追加」ボタンが有効化されます。
</p>
</div>
</div>
</validation-observer>
</div>
</section>
</template>
<script>
import TextFieldWithValidation from '@/components/TextFieldWithValidation'
export default {
name: 'HomePage',
components: {
TextFieldWithValidation
},
data () {
return {
textValue: '',
emailValue: ''
}
}
}
</script>
ポイントとなるのは、
との間にあるフォームはVeeValidateの監視下となり、その中にあるフォームでバリデーションが通らないものがある場合は
invalid
がtrueとなります。そしてこのinvalid
がtrueである場合は、送信ボタンに:disabled="invalid"
を付与することで無効化しています。
また、メールアドレスのフォームでは、rules="required|email"
としており、これはrequired
(必須項目のバリデーション)、email
(正しいメールアドレスのバリデーション)の2つを指定しています。このようにパイプ|
でルールを繋ぐことで複数指定することができます。
なお、上記の
は、新しく作成したコンポーネントです。各自のNuxt.jsアプリのルートディレクトリにあるcomponents
ディレクトリ下に作成し、以下のようにします。
<template>
<validation-provider v-slot="{ errors }" :rules="rules" :name="fieldname">
<input
v-model="innerValue"
:placeholder="fieldname"
/>
<p v-show="errors.length" class="help is-danger">
{{ errors[0] }}
</p>
</validation-provider>
</template>
<script>
export default {
name: 'TextFieldWithValidation',
props: {
rules: {
type: String,
required: true
},
value: {
type: String,
required: true
},
fieldname: {
type: String,
required: true
}
},
computed: {
innerValue: {
get () {
return this.$props.value
},
set (val) {
this.$emit('input', val)
}
}
}
}
</script>
上記のform.vue
は表示すると以下のような見た目になります。
具体的な説明は公式ドキュメントに譲りますが、おそらく各記述と実際のフォームの見た目を照らし合わせれば理解できると思います。
なお、上記の例では、バリデーションが通るまではボタンを無効化していますが、もし:disabled
を付与せずに試しにバリデーションが通る前に送信してみると、実際には送信できてしまいます。
すなわち、例えば送信ボタンのクリックに何かしらのメソッドを結びつけている場合は、そのメソッドは実行されます。これを防ぐには、以下のようにValidationObserverにpasses
を加えて、さらに送信ボタンに結びつけるメソッドをpasses(submit)
のように引数としてpasses
に与えます。以下は公式ドキュメントからの引用です。
<template>
<validation-observer v-slot="{ invalid, passes }">
<form @submit.prevent="passes(submit)">
<text-field-with-validation rules="required" v-model="first" />
<text-field-with-validation rules="required" v-model="second" />
<button :disabled="invalid">Submit</button>
</form>
</validation-observer>
</template>
<script>
export default {
methods: {
submit() {
// メソッドには追記修正不要
}
}
};
</script>
バリデーションが通らない時に送信ボタンを押下された場合に自身で処理を記述したい場合は、passes
を使わずに以下のようにすることもできます。
<template>
<validation-observer ref="observer" v-slot="{ invalid }" tag="form" @submit.prevent="submit()">
<text-field-with-validation rules="required" v-model="first" />
<text-field-with-validation rules="required" v-model="second" />
<button :disabled="invalid">Submit</button>
</validation-observer>
</template>
<script>
export default {
methods: {
async submit () {
const isValid = await this.$refs.observer.validate();
if (!isValid) {
// バリデーションが通る前に送信ボタンがクリックされた場合の処理
}
// バリデーションが通っている状態で送信ボタンがクリックされた場合の処理
}
}
};
</script>
上記についてはいずれも公式ドキュメントに詳しく記載されています。
フォーム送信後にバリデーションをリセットする(#2019/9/15 追記)
上記のValidatioObserverの例だと、フォームを送信直後にフォーム内容をリセットしています。この場合、フォームを送信して空になった時点でバリデーションがかかってしまいバリデーションエラーが表示されます。これを防ぐには、フォーム送信完了後にリセットする必要がありました。以下がコードになります。
<template>
<validation-observer ref="observer" v-slot="{ invalid }" tag="form" @submit.prevent="submit()">
<text-field-with-validation rules="required" v-model="first" />
<text-field-with-validation rules="required" v-model="second" />
<button :disabled="invalid">Submit</button>
</validation-observer>
</template>
<script>
export default {
methods: {
async submit () {
const isValid = await this.$refs.observer.validate();
if (!isValid) {
// バリデーションが通る前に送信ボタンがクリックされた場合の処理
}
// バリデーションが通っている状態で送信ボタンがクリックされた場合の処理
// フォーム送信などの処理完了後、以下のリセットを呼び出す。
requestAnimationFrame(() => {
this.$refs.observer.reset()
})
}
}
};
</script>
ref="observer"
でValidatioObserverの名前を指定しており、これに対するリセットをかけていることに注意してください。
なお、リセットに関する公式ドキュメントは以下になります。
Like the validate method, we could also reset our form after submitting the values to the server
まとめ
VeeValidateはバージョン2系から3系で大きく変わっていますが、3系も一度理解できればすんなり使用でき、また柔軟性も向上している印象です。
関連記事
- 公開日:2022/08/11 更新日:2020/08/11
fontawesome-svg-coreが原因でnuxt generateが失敗する時の回避策
Netlifyにいつも通りNuxt.jsで作成したサイトをデプロイしようとしたところ、nuxt generate時にfontawesome-svg-coreについてエラーがでました。この回避策をメモします。
- 公開日:2020/03/18 更新日:2020/03/18
nuxt-i18nを使ってNuxt.jsを多言語化する手順
Nuxt.jsで表示を日本語と英語の両方を表示できるようにし、さらに日本語と英語を切り替えするためのボタンも実装したのでその手順をまとめます。ここではnuxt-i18nというプラグインを使用します。
- 公開日:2019/10/10 更新日:2019/10/10
Nuxt.js + Buefyでローディング画像を表示する
Nuxt.jsでBuefyを使っている前提となりますが、axiosで何かしらのファイルをダウンロードしている間などユーザに処理中であることを示すためにローディング画像を表示するよう実装しました。その手順をまとめます。非常に簡単に実装できます。
- 公開日:2019/10/03 更新日:2019/10/03
Nuxt.jsからGoogleスプレッドシートのデータを読み書きする
Nuxt.jsからGoogleスプレッドシートのデータを読み込んだり書き込んだりしたのでその手順をまとめます。
- 公開日:2019/09/22 更新日:2019/09/22
Nuxt.js(Vue.js)+ Buefy でCSVファイルをアップロードしてテーブル表示する
Nuxt.jsでBuefyを使っており、csvファイルをアップロードして読み込ませる必要がったので実装してみました。この記事では、Buefyというコンポーネントセットを使っています。