Element plus 图片手动上传与回显

近期,发现点击修改,element ui 的图片没有回显到框中,记载一个实现过程。

1. 图片手动上传,等待上传成功。

这里关键点设置关闭自动上传,用于手动提交,设置上传地址和请求头信息。success函数和error函数监听结果。

  • :auto-upload="false":禁止自动上传
  • :action=uploadUrl 设置上传地址
  • :headers="headers" 设置上传请求头信息
  • :file-list="form.files" 将自定义对象加入到列表中
  • :on-success="handleAvatarSuccess":上传成功函数
  • :on-error="handleError":上传失败函数
html 复制代码
<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 自定义函数。作用是等待上传结果。

js 复制代码
try {
    await this.submitUpload()
} catch (e) {
    this.$message.warning('请重新上传图片~~')
return
}

这里通过 Promise 实现等待效果。通过 this.$refs.upload.submit() 方法进行上传图片。

this.uploadPromiseResolve 和 this.uploadPromiseReject 是自定义参数,获取到当前Promise 的 resolve, reject 引用,从而实现等待,如果没有这两个,该函数将不会等待。当值有引用时,该对象不会被释放,从而等待。

js 复制代码
// 包装 submit 方法,返回 Promise
async submitUpload() {
  return new Promise((resolve, reject) => {
    this.$refs.upload.submit()
    this.uploadPromiseResolve = resolve
    this.uploadPromiseReject = reject
  })
},

这个时候成功上传函数或者失败函数会被调用,成功则把图片地址复制给当前表单,然后将响应结果赋值并释放,一定要释放。失败则直接释放。

js 复制代码
//图片上传成功
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 函数,传入图片,多张图片由逗号分隔。看下具体实现。

js 复制代码
/** 修改按钮操作 */
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 需要的格式对象返回即可。

js 复制代码
// 将二进制数据转换成可访问的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
                };
            })
        )
    }
}
相关推荐
天天向上102413 分钟前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y28 分钟前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁35 分钟前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry35 分钟前
Fetch 笔记
前端·javascript
拾光拾趣录37 分钟前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟37 分钟前
vue3,你看setup设计详解,也是个人才
前端
Lefan41 分钟前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构
vvilkim1 小时前
Nuxt.js 全面测试指南:从单元测试到E2E测试
开发语言·javascript·ecmascript
写不出来就跑路1 小时前
基于 Vue 3 的智能聊天界面实现:从 UI 到流式响应全解析
前端·vue.js·ui