更新於 2024/10/24閱讀時間約 4 分鐘

在 Vue 中用原生 input file 上傳圖片後預覽

  先前在開發的專案中,需要一個上傳圖片後可以看即時看到預覽的功能。再加上這個功能在許多地方都會用到,因此試著製作了一個可以獨立運行的組件。

  因為把上傳區跟預覽區分開,因此如果從其它組件取得 previews 資料並放入 previews 陣列中的話,也可以做到直接預覽圖片的功能。


設計的想法是這樣的:

  • 利用原生的 <input type=”file”> 來選擇要上傳的圖片。
  • 另外設定一個 <img> 容器去顯示圖片。
  • 取得所選圖片的URL,放進 <img> 的 src 中。
    • 抓到 <input type=”file”> 上傳的 file 物件
    • 用 URL.createObjectURL() 可以將所選取的 file 物件轉成URL。
    • 把 URL 塞進 src 中。


用Vue來實作:

<template>
<!-- 輸入檔案的地方 -->
<input
ref="uploadFile"
id="uploadFile"
type="file"
name="imgUpload"
@change="changeFile($event)"
/>

<!-- 預覽圖片的地方,因為可能會有多檔上傳,因此用 v-for 來讓多張圖片可以一張一張渲染 -->
<div v-for='file of previews'>
<img
:src="file.url"
:alt="file.name"
v-if="uploadFile !== null"
/>
</div>
</template>

<script setup>
const previews = ref([])
function changeFile(e) {
const uploadFile = e.target.files
//uploadFile是一個陣列,因為有可能會有多檔上傳的情況,因此用陣列的模式去處理。
uploadFile.forEach((file) => {
const item = {}
item.name = '圖片名稱'
item.url = URL.createObjectURL(uploadFile)
previews.value.push(item)
})
}
</script>


在 Vue 中遇上的問題及解決方法


該如何抓到上傳的檔案
  vue 中的 v-model 對於 input:file 是無效的,因此無法用 v-model 的方式取得值,但可以用事件的方式取得,因此這邊使用 @change=”changeFile($event)” 來利用事件取得 input:file 這個元素。並用 e.target.files 來抓到檔案。


參考資料

不用靠後端的 client 端上傳圖片預覽圖

MDN - URL.createObjectURL()

如何用Vue 寫圖片上傳與預覽?


如果有更好的寫法,或是有錯誤之處都歡迎提出!

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.