環境
Nuxt.js, Vuetify
やりたいこと
<v-form>
を使ってフォームを作り、その中で少なくとも一枚以上の写真を要求したい。そして取得した写真を表示したい。
写真がない時

写真がある時

実装
item_register.vue
<template>
<v-card>
<v-card-text
v-if="!validInput"
style="color: red"
>
最低一枚以上の写真が必要です
</v-card-text>
<v-file-input
required
class="pa-4"
multiple
label="写真を追加して下さい(複数可)"
filled
accept="image/*"
prepend-icon="mdi-camera"
@change="onChangeImage"
/>
</v-card>
</template>
<script>
export default {
data() {
return {
imageUrls: []
}
},
computed(){
// imageUrlsに写真があるときはtrue、ない時はfalse
validInput(){
return this.imageUrls.length > 0 ? true : false;
},
},
methods(){
// ファイルをbase64を用いて変換
getBase64(file){
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = error => reject(error);
});
},
// ファイルが入力されたときに使うメソッド
onChangeImage(File) {
// 配列を一回初期化してから追加する必要がある。そうしないとどんどん写真が追加されていってしまう。
this.imageUrls = [];
File.forEach(file => {
this.getBase64(file)
.then(image => {
this.imageUrls.push(image);
})
.catch(error => console.log(error));
});
},
}
}
<script/>
実装にあたってのポイント
バリデーション
今回使ったv-file-input
というコンポーネントは、rules
プロパティを指定することでバリデーションを追加できる。しかし、このrulesでは画像サイズのバリデーション等は実装できるものの、ファイル数についてはうまく動くrulesを設定できなかった。そのため、computedにinputファイル数によってtrue/falseを返すvalidInputを実装し、それをv-ifを使って表示することでバリデーションを実装した。