概要
画像のwidthとheightを何px以下にするっていうバリデーションがしたかった。
が、VeeValidateにデフォルトであるRuleにはそんなものはなかったし、追加するつもりもなさそうだった。
https://github.com/logaretm/vee-validate/pull/2052
環境
- Nuxt
- TypeScript
- Vuetify
- VeeValidate
結論
自前でルール定義しよ
src/plugins/vee-validate.ts
import Vue from 'vue'
import VeeValidate, { Validator, Rule, RuleResult } from 'vee-validate'
import ja from 'vee-validate/dist/locale/ja'
Vue.use(VeeValidate)
Validator.localize('ja', ja)
// HACK: カスタムルールは別ファイル化の方がよき
const loadImage = (src: string): Promise<HTMLImageElement> => {
return new Promise((resolve, reject): void => {
const image: HTMLImageElement = new Image()
image.onload = (): void => resolve(image)
image.onerror = (e): void => reject(e)
image.src = src
})
}
const maxDimensionsRule: Rule = {
validate: (file: File, pixel): RuleResult => {
const url = window.URL
// HACK: promise型を返したくないからthen使ってる
const isVelify = loadImage(url.createObjectURL(file)).then(
(response: HTMLImageElement): boolean => {
if (response.width > Number(pixel)) {
return false
}
if (response.height > Number(pixel)) {
return false
}
return true
}
)
return isVelify
},
getMessage: (field: string, [pixel]: [number]): string => {
return `${field}は幅${pixel}px、高さ${pixel}px以下にしてください`
}
}
Validator.extend('maxdimensions', maxDimensionsRule)
詳細
今回は画像の縦横同じ大きさでよかったので指定するpixelは一つだけにしましたけども引数増やせば縦横別々の指定もできそう。
あとはいつものようにルールを呼び出すのみ
<v-file-input
v-model="imageFile"
v-validate="{
maxdimensions: 1024
}"
></v-file-input>