【elementui】el-upload 自定义且一次性上传多个文件

本文介绍如何使用El-upload组件实现表单中的文件上传,包括校验文件、格式转换和接口调用策略。重点在于确保所有文件上传成功后再进行下一步操作。

业务需求

  • 填写表单字段
  • 手动选择文件
  • 点击保存上传文件并保存表单

思路

  • 校验表单
  • 校验已选择文件
  • 触发 el-upload 文件上传函数
  • 每个文件做一次格式转换(如果格式一致可忽略)
  • 判断所有文件的状态是否都是成功状态
  • 所有文件上传成功才调用接口
<el-form ref="form" :model="form">
    <el-form-item>
    <!--其他表单字段-->
        <el-input> 
    </el-form-item>
	<el-upload
	   :action="upload.actionUrl"
	   :file-list="fileList"
	   :on-success="handleUploadSuccess"
	   :on-change="handleChange"
	   :show-file-list="true"
	   :headers="upload.headers"
	   
<think>好的,用户在使用elementUI-plus的el-upload组件遇到了on-success被调用两次的问题。需要找出原因并给出解决方法。 首先,根据用户提供的代码,他们使用了http-request自定义上传方法,并在其中手动调用了onSuccess。同,组件上还绑定了:on-success属性。这可能导致了重复调用,因为当使用http-request覆盖默认上传,on-success可能会在手动调用和组件内部触发两次。 参考引用中的示例,用户确实在http-request的实现里执行了onSuccess,而组件本身可能也会触发on-success事件。这种情况下,每次上传成功,onSuccess会被调用两次:一次是手动触发,另一次是组件默认行为。 解决方法应该是避免同使用http-request和on-success属性。用户需要检查代码,确保在自定义上传方法中只调用一次onSuccess,并移除组件上的:on-success绑定。此外,确保没有其他地方的代码重复触发成功事件,比如在Promise链中次调用onSuccess或误用其他钩子函数。 还需要验证是否在uploadFile方法中正确调用了onSuccess,并没有在.then()之后再次触发。同,检查是否有其他事件监听器或父组件的影响。最终,通过移除冗余的on-success属性,并确保只在http-request中处理成功回调,应该能解决调用两次的问题。</think>### 问题原因分析 在 ElementUI Plus 的 `el-upload` 组件中,使用 `http-request` 自定义上传方法,若同绑定 `on-success` 事件,可能导致回调被重复触发。主要原因如下: 1. **手动调用 `onSuccess` 与自动触发冲突**:在自定义的 `http-request` 方法中,若主动调用 `onSuccess`,而 `el-upload` 组件本身也会根据请求结果自动触发 `on-success`,导致重复执行[^1][^2]。 2. **异步操作未正确终止**:若自定义上传方法的 Promise 链未正确控制(例如重复调用 `resolve` 或 `onSuccess`),可能触发次回调。 --- ### 解决方案 #### 1. **移除冗余的 `on-success` 绑定** 在模板中删除 `:on-success` 属性,仅通过 `http-request` 方法控制回调逻辑: ```html <el-upload :http-request="(e) => uploadFile(e, row)" :file-list="row.imageCos || []" > <!-- 其他配置 --> </el-upload> ``` #### 2. **规范 `http-request` 实现** 在自定义上传方法中: - **仅调用一次 `onSuccess`** - **避免与其他钩子函数冲突** ```javascript uploadFile({ file, onProgress, onSuccess }, row) { uploadPic(file, progress => onProgress(progress)) .then(res => { // 手动触发成功回调,并传递必要参数 onSuccess({ name: res.name, url: res.url }); }) .catch(error => { // 处理错误 }); } ``` #### 3. **检查 Promise 链完整性** 确保上传逻辑的 Promise 链中不会重复调用 `resolve` 或 `reject`,例如: ```javascript // 原代码中的潜在问题 .then(res => { onSuccess(...); // 第一次触发 resolve(res); // 可能导致第二次触发 }) ``` --- ### 完整代码示例 ```html <el-upload :http-request="(e) => uploadFile(e, row)" :file-list="row.imageCos || []" ref="uploadPic" list-type="picture-card" > <i class="el-icon-plus"></i> </el-upload> ``` ```javascript uploadFile({ file, onProgress, onSuccess }, row) { uploadPic(file, progress => onProgress(progress)) .then(res => { onSuccess({ name: res.name, url: res.url }); // 仅此处触发一次 this.$set(row, &#39;imageCos&#39;, [...row.imageCos, res]); }) .catch(error => { Message.error(&#39;上传失败&#39;); }); } ``` --- ### 关键验证点 1. **移除 `:on-success` 绑定**:确保模板中无 `on-success` 相关属性。 2. **避免双重回调**:不在 `http-request` 内外同触发成功事件。 3. **检查异步逻辑**:确认上传函数未在多个位置调用 `onSuccess` 或 `resolve`。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值