ファイルアップロード時に複数の画像プレビューを表示する
題名の通りですが、今回は備忘録として、
画像アップロードを行う際に複数の画像プレビューを
Vue.jsを利用して表示する方法について書いていこうと思います。
FileAPI
FIleAPIについては以下のドキュメントを参照してください。
https://developer.mozilla.org/ja/docs/Web/API/File
実装例
<template>
<div>
<input
@change="inputFileList($event)"
multiple="multiple"
accept="image/*"
>
<div
v-for="(uploadFile, index) in updatedFileList"
:key="index"
>
<p>ファイル名: {{ uploadFile.fileName }}</p>
<p>ファイルタイプ: {{ uploadFile.fileType }}</p>
<p>サイズ: {{ uploadFile.size.width }}×{{ uploadFile.size.height }}</p>
<img :src="uploadFile.url">
</div>
</div>
</template>
<script>
export default {
data: {
uploadFileList: []
}
computed: {
// this.uploadFileListに変更が加わった際に検知するためです
uploadFileList() {
return this.uploadFileList
}
}
methods: {
async inputFileList(event) => {
// event.target.filesはファイルデータが格納されたリストです
const fileList = event.target.files
if (fileList === 0) {
return
}
// FileAPIは、APIなので複数ファイルを扱う時は、
// for文の中でawaitする必要があります
for (file of fileList) {
// ファイルデータ用のオブジェクトを用意します
const fileData = {
name: '',
type: '',
size: { width: 0, height: 0 },
url: ''
}
const image = new Image()
const fileReader = new FileReader()
// 即時関数をawaitすることで処理の完了までループが終わりません
await (async () => {
fileReader.onload = async () => {
image.src = fileReader.result
// ファイルURL取得
fileData.url = fileReader.result
// 即時関数をawaitすることでfileData.sizeのデータを担保します
await (() => {
image.onload = () => {
// ファイルサイズ取得
fileData.size = { width: image.naturalWidth, height: image.naturalHeight }
}
})()
}
// FileAPIの起動
fileReader.readAsDataURL(file)
})()
// 取得したファイルデータのオブジェクトをuploadFileListにpushします
this.uploadFileList.push(fileData)
}
}
}
}
##おわりに
間違いや質問などありましたらコメントお願いします。