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
                };
            })
        )
    }
}
相关推荐
foxhuli22937 分钟前
禁止ifrmare标签上的文件,实现自动下载功能,并且隐藏工具栏
前端
青皮桔1 小时前
CSS实现百分比水柱图
前端·css
失落的多巴胺1 小时前
使用deepseek制作“喝什么奶茶”随机抽签小网页
javascript·css·css3·html5
DataGear1 小时前
如何在DataGear 5.4.1 中快速制作SQL服务端分页的数据表格看板
javascript·数据库·sql·信息可视化·数据分析·echarts·数据可视化
影子信息1 小时前
vue 前端动态导入文件 import.meta.glob
前端·javascript·vue.js
青阳流月1 小时前
1.vue权衡的艺术
前端·vue.js·开源
RunsenLIu1 小时前
基于Vue.js + Node.js + MySQL实现的图书销售管理系统
vue.js·mysql·node.js
样子20181 小时前
Vue3 之dialog弹框简单制作
前端·javascript·vue.js·前端框架·ecmascript
kevin_水滴石穿1 小时前
Vue 中报错 TypeError: crypto$2.getRandomValues is not a function
前端·javascript·vue.js
翻滚吧键盘1 小时前
vue文本插值
javascript·vue.js·ecmascript