はじめに
「サーバーへリクエスト送信する前に、フロント(Vue)側でバリデーションをかけるには何を実装すればいいんだ?」と疑問を持たれている方向けに投稿しました。
開発環境
言語(FW,ライブラリ) | バージョン |
---|---|
vue.js | 2.6.14 |
nuxt.js/composition-api | ^0.33.1 |
vee-validate | 3 |
node | 16.11.0 |
vee-vallidateとは
Vue.jsでリアルタイムバリデーションを行うためのライブラリです。
入力時に不正な値があった場合、サーバーへ送信する前にエラーを表示させることができます。
実装内容
ユーザー登録時のパスワード入力のバリデーションエラーを表示する。
仕様
- パスワードには大文字・小文字・数字がそれぞれ1文字以上含まれていること。含まれていなかったものがあれば、バリデーションエラーを返す
- パスワードは8文字以上16文字以内で入力されていること。8文字未満もしくは16文字を超えた場合はバリデーションエラーを返す
コードの例
説明の関係上で一部省略しておりますので、ご了承ください🙏
ユーザー登録フォーム(必須項目のみ抜粋)
components/molecules/userForm.vue
<template>
<validation-observer ref="observer" v-slot="{ invalid }">
<validation-provider
v-slot="{ errors }"
rules="'required|email'"
name="メールアドレス"
>
<v-text-field v-model="newUser.email" :error-messages="errors"></v-text-field>
</validation-provider>
<validation-provider
v-slot="{ errors }"
:rules="{ required: true, minmax: { min: 6, max: 16 }, password_regex }"
name="パスワード"
>
<v-text-field v-model="newUser.password" type="password" :error-messages="errors" hint="パスワードには大文字、小文字、数字、記号を含む少なくとも8文字以上の入力が必須です"></v-text-field>
</validation-provider>
</validation-observer>
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from '@vue/composition-api'
export default defineComponent({
setup(props, { emit }) {
interface newUser {
email: string
password: string
}
const newUser = reactive<newUser>({ email: '', password: '' })
const observer = ref()
return {
newUser,
observer
}
}
})
</script>
補足
-
validation-observer
:フォーム全体の検証結果を管理し、有効な状態かどうかを判断します -
validation-provider
:フォーム内で個別に検証ルールを適用して有効かどうかを判断します -
v-slot
:親コンポーネントから子コンポーネントへコンテンツ(invalidプロパティ
)を渡します -
invalid
: trueの時、フォームにエラーがあり、送信できない状態(falseはその逆) -
rules
: 各フィールドのバリデーションのルールを定義しています。例えばrequiredは、veeValidate(ライブラリ)で標準の機能として用意されています。
もし用意されていなければカスタムルールを自分で作成する必要があります。
カスタムのバリデーション
plugin/vee-validate.js
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 (const rule in rules) {
extend(rule, rules[rule])
}
extend('password_regex', {
validate(value) {
const regex = /(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)/.test(value);
return regex
},
message:
'英大文字、英小文字、数字を含む8文字以上の入力が必須です',
})
extend('minmax', {
validate(value, params) {
const length = value.length;
return length >= params.min && length <= params.max;
},
params: ['min', 'max'],
message: "{_field_}は8文字以上16文字以内で入力してください"
});
Vue.component('ValidationProvider', ValidationProvider)
Vue.component('ValidationObserver', ValidationObserver)
localize('ja', ja)
補足
-
extend
: カスタムルールを追加する際に使用されるVeeValidateの関数です。Vueアプリケーション内のどのコンポーネントからでもグローバルに利用することができます -
validate
: この関数で非同期的に入力値を即座にチェックします -
params
: 各フィールドで指定した引数名をプロパティとして定義し、バリデーションロジック内でパラメータとして受け取ります。今回の場合はコンポーネントのrulesに指定したminとmaxを指定しています -
value
: バリデーションの対象となる値です。フィールドに入力された文字列などを指します
結果
ダイアログを開いてフォーム入力し、バリデーションが発生してから、入力したデータの送信が可能になるまでの流れを画像でまとめました。
まとめ
- Vue.jsでカスタムのバリデーションを作成する際に、VeeValidateでリアルタイムバリデーションが実装できる
- 即座に入力ミスの結果がフィードバックされるため、ユーザーにとっては作業の効率化やユーザーエクスペリエンスの向上に繋がる