> 先前在 [Vue.js ecshop 專案 6.props & emit 資料傳遞](https://hackmd.io/@emma-huang/HyU1vmi9C) 文章中有分享過 **新增商品** 的功能,此篇文章要補充其中 **上傳圖片** 的功能,那我們就開始吧! ### 透過 API 上傳圖片 * 在 ***ProductModal.vue*** 下方這段程式碼新增 `ref`、`@change` 片段 ```html= <div class="mb-3"> <label for="customFile" class="form-label">或 上傳圖片 <i class="fas fa-spinner fa-spin"></i> </label> <input type="file" id="customFile" class="form-control" ref="fileInput" @change="uploadFile"> </div> ``` * 依照 API 提供的上傳圖片格式 `multipart/form-data` 新增上傳事件 <img src="https://firebasestorage.googleapis.com/v0/b/emmablog-e5a1c.appspot.com/o/uploadfile.png?alt=media&token=e4c71fa2-bdaa-4baf-a00b-f5f0a5d6fa7e"> * 新增 `uploadFile()` 事件 * 其中使用 `new FormData()` 來建立一個 `form-data` 格式的內容 * 接著透過 `formData.append('欄位名稱', 上傳的資料)` 來增加欄位到表單中 * 再透過上傳檔案的 API 做推送 ```javascript= uploadFile () { const uploadedFile = this.$refs.fileInput.files[0] // 建立一個 form-data 格式的內容 const formData = new FormData() // 增加欄位到表單中(欄位名稱, 上傳的資料) formData.append('file-to-upload', uploadedFile) const api = `${process.env.VUE_APP_API}api/${process.env.VUE_APP_PATH}/admin/upload` this.axios.post(api, formData) .then((res) => { console.log(res) }) } ``` <img src="https://firebasestorage.googleapis.com/v0/b/emmablog-e5a1c.appspot.com/o/uploadFile_demo.png?alt=media&token=319a724c-3aa2-48e6-83f2-794279a6155b"> * 圖片成功上傳後,在 `console` 可以看到 `data` 裡面會有 `imageUrl` <img src="https://firebasestorage.googleapis.com/v0/b/emmablog-e5a1c.appspot.com/o/imageUrl.png?alt=media&token=02f5767a-31ea-4df6-9de7-3a235f0e4e9e"> * 最後再加上判斷式 **讓圖片 `imageUrl` 儲存到 `tempProduct`** ```javascript=9 this.axios.post(api, formData) .then((res) => { if (res.data.success) { this.tempProduct.imageUrl = res.data.imageUrl } }) ``` * 調整後完整的程式碼如下: ```javascript= uploadFile () { const uploadedFile = this.$refs.fileInput.files[0] // 建立一個 form-data 格式的內容 const formData = new FormData() // 增加欄位到表單中(欄位名稱, 上傳的資料) formData.append('file-to-upload', uploadedFile) const api = `${process.env.VUE_APP_API}api/${process.env.VUE_APP_PATH}/admin/upload` this.axios.post(api, formData) .then((res) => { if (res.data.success) { this.tempProduct.imageUrl = res.data.imageUrl } }) } ```