近期,發現點選修改,element ui 的圖片沒有回顯到框中,記載一個實現過程。
1. 圖片手動上傳,等待上傳成功。
這裏關鍵點設定關閉自動上傳,用於手動提交,設定上傳地址和請求頭資訊。success函式和error函式監聽結果。
:auto-upload="false":禁止自動上傳
:action=uploadUrl 設定上傳地址
:headers="headers" 設定上傳請求頭資訊
:file-list="form.files" 將自定義物件加入到列表中
:on-success="handleAvatarSuccess":上傳成功函式
:on-error="handleError":上傳失敗函式
<el-upload ref="upload" :auto-upload="false" :action=uploadUrl :headers="headers" :file-list="form.files" name="file" list-type="picture-card" :on-progress='handPic' :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handleAvatarSuccess" :on-error="handleError" >
邏輯實現,因為後端返回的是一個圖片地址,這裏新增的時候需要拿到圖片上傳結果,並複製給物件,進行新增,當點選提交表單後:呼叫submitUpload 自定義函式。作用是等待上傳結果。
try { await this.submitUpload() } catch (e) { this.$message.warning('請重新上傳圖片~~') return }
這裏透過 Promise 實現等待效果。透過 this.$refs.upload.submit() 方法進行上傳圖片。
this.uploadPromiseResolve 和 this.uploadPromiseReject 是自定義引數,獲取到當前Promise 的 resolve, reject 引用,從而實現等待,如果沒有這兩個,該函式將不會等待。當值有引用時,該物件不會被釋放,從而等待。
// 包裝 submit 方法,返回 Promise async submitUpload() { return new Promise((resolve, reject) => { this.$refs.upload.submit() this.uploadPromiseResolve = resolve this.uploadPromiseReject = reject }) },
這個時候成功上傳函式或者失敗函式會被呼叫,成功則把圖片地址複製給當前表單,然後將響應結果賦值並釋放,一定要釋放。失敗則直接釋放。
//圖片上傳成功 handleAvatarSuccess(response) { this.form.img = response.fileName this.uploadPromiseResolve(response) this.uploadPromiseResolve = null }, handleError(error) { this.uploadPromiseReject(error) this.uploadPromiseReject = null }
回到剛剛的函式中。整個流程就到完成了。
2. 回顯是如何實現的?
需求是點選修改,將獲取介面中的圖片地址路徑,進行渲染該圖片。
透過 getDevice 獲取到當前裝置資訊,有 img 屬性表示圖片。
接下來,呼叫 getImgForObject 函式,傳入圖片,多張圖片由逗號分隔。看下具體實現。
/** 修改按鈕操作 */ async handleUpdate(row) { this.reset() const id = row.deviceNumber || this.ids const {data} = await getDevice(id, this.form.deviceType) this.form = data this.form.files = await getImgForObject(data.img) this.title = '修改裝置' this.open = true }
這裏說下邏輯,透過獲取的路徑,去呼叫該介面,獲取二進制資料,將二進制轉換成 blob物件,再使用 URL.createObjectURL() 建立當前頁面可訪問的圖片地址。為什麼是當前頁面可訪問呢,因為這個是臨時地址,只能被當前會話訪問。最後封裝ELement ui 需要的格式物件返回即可。
// 將二進制資料轉換成可訪問的Element ui 物件 export async function getImgForObject(imgs) { if (imgs) { return await Promise.all( imgs.split(',').map(async item => { const blob = await getImg(item) // 將 Blob 物件轉換為 File 物件 const split = item.split('/') const file = new File([blob], split[split.length - 1], {type: blob.type}) // 建立唯一的 uid (可以根據實際需求生成唯一標識) const uid = Date.now() // 使用 URL.createObjectURL() 建立可訪問的本地 url const fileUrl = URL.createObjectURL(blob) // 構建 File 物件並返回 return { name: file.name, percentage: 0, // 初始上傳進度為 0 raw: file, // Blob 轉換為 File size: file.size, // 檔案大小 status: 'ready', // 狀態設為 ready uid: uid, // 唯一識別符號 url: fileUrl // 使用 createObjectURL 生成的本地 URL }; }) ) } }