宮崎在住エンジニアのジョウ(@JotarO_Oyanagi) です。
Vue 用のバリデーションプラグイン VeeValidate。
ディレクティブで適用させることができ、config ファイルで細かくカスタマイズできたりと、設定が楽なことからお気に入りのプラグインです。
VeeValidate でのフォームの一括バリデートは「コンポーネントごと」となってしまうため、フォームをコンポーネントに分けた場合、親コンポーネントから一括バリデートをするには一手間かかります。
すべての子コンポーネントでバリデートをし、その結果を受け取る仕組みを async / await
を使って実装してみました。
TL;DR
- VeeValidate を使用して、複数の子コンポーネントのフォームをバリデート
- 各フォームコンポーネントの
$validator.validateAll()
の結果を親コンポーネントで取得 -
async / await
を使って実装
実装してみる
VeeValidate の実装方法は公式や以下の記事をご参照ください。
VeeValidate を使用しているコンポーネント Form1, Form2, Form3 がある場合、親コンポーネントの vue ファイルは以下のように記述します。
parent.vue
<template>
<div>
<form1 ref="Form1"/>
<form2 ref="Form2"/>
<form3 ref="Form3"/>
<button @click="getAllValidationResult">
確認
</button>
</div>
</template>
<script>
// それぞれのコンポーネントで VeeValidate を使用
import form1 from './form1'
import form2 from './form2'
import form3 from './form3'
export default {
components: {
form1, form2, form3
},
methods: {
validateAllForms: async function () {
// $validator.validateAll() は、エラーがなければ true が返る
// 一つでもエラーがあれば false が返る
const isOkForm1 = await this.Form1.$validator.validateAll(),
isOkForm2 = await this.Form2.$validator.validateAll(),
isOkForm3 = await this.Form3.$validator.validateAll()
// すべての await が処理されたら return
return isOkForm1 && isOkForm2 && isOkForm3
},
getAllValidationResult () {
this.validateAllForms()
.then((response) => {
// すべてのフォームでエラーがなければ response は true になる
if (response) {
// 全フォームでエラーがない場合の処理
}
})
}
}
}
</script>
おわりに
子コンポーネントの関数を直接実行するのでアンチパターンな気がしますが、emit を使用した方法が思いつきませんでした...。
この方法で行くのなら $validator.validateAll()
は直接実行せず、ラッパーをかませた方がいいですね。
参考資料
- VeeValidate
- Vue.jsを使ってて、フロントサイドのバリデーションには VeeValidate が便利
- async/await 入門(JavaScript)