[Vue3]VeeValidate4でinput type="file"のバリデーション
概要
業務でVue2->Vue3のプロジェクトに参画しており、VeeValidate3で実装していたinput type=fileのバリデーションの移行にハマってしまったため備忘として残します。
なお筆者はフロント経験は浅く、ご指摘など滝のようにいただけますと幸いです。
やりたいこと
画像ファイルのアップロードができるコンポーネントで、バリデーションルールが文字列で size:2000|mimes:image/*
のように指定される。
inputの@changeイベントで選択されたファイルに対し指定のルールでバリデーションをかけて、エラーであればエラーメッセージを表示したい。
バリデーションルールは自作せずにVeeValidate組み込みのルールを使用したい。
実装
'size:2000|mimes:image/*'
という文字列のルールで、2000KBまでの画像に制限するバリデーションを行いたいとします。
template
<template>
<div>
<h1>ファイルを選択</h1>
<input type="file" @change="handleFileChange" />
<p>{{ errorMessage }}</p>
</div>
</template>
例として簡単に記述します。特にVeeValidate関連の記述はありません。
script
import { defineRule, useField } from 'vee-validate'
import { mimes, size } from '@vee-validate/rules'
VeeValidateから必要なものをインポートします。
上記のmimes, sizeが、それぞれファイルを画像に制限する・ファイルサイズを制限するための組み込みのルールです。
利用できるルールは以下に記載があります。
defineRule('size', size)
defineRule('mimes', mimes)
文字列で指定されるルールのsize
mimes
をそれぞれ組み込みのルールに紐づけるためにdefineRuleで定義します。
const { value, validate, errorMessage } = useField('file', 'size:2000|mimes:image/*')
useFieldの第2引数にルールを渡し、対象のファイルデータを格納するvalue、バリデーションを実行するメソッドのvalidate、バリデーションがエラーとなった場合のエラーメッセージが格納されるerrorMessageを取得します。
const handleFileChange = async (event: Event) => {
const target = event.target as HTMLInputElement
const file = target.files?.[0]
if (!file) return
value.value = file
await validate()
}
inputの@changeイベントで発火し、useFieldで取得したvalueにeventのファイルを格納してvalidate()を実行するメソッドを定義します。
<script setup lang="ts">
import { defineRule, useField } from 'vee-validate'
import { mimes, size } from '@vee-validate/rules'
defineRule('size', size)
defineRule('mimes', mimes)
const { value, validate, errorMessage } = useField('file', 'size:2000|mimes:image/*')
const handleFileChange = async (event: Event) => {
const target = event.target as HTMLInputElement
const file = target.files?.[0]
if (!file) return
value.value = file
await validate()
}
</script>
<template>
<div>
<h1>ファイルを選択</h1>
<input type="file" @change="handleFileChange" />
<p>{{ errorMessage }}</p>
</div>
</template>
全体は上記のようになります。
確認
csvを選択した時、2000KBを超えるサイズの画像を選択した時それぞれエラーメッセージが表示されました。
Discussion