切換語言為:簡體

Element plus 圖片手動上傳與回顯

  • 爱糖宝
  • 2024-09-21
  • 2063
  • 0
  • 0

近期,發現點選修改,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
                };
            })
        )
    }
}

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.