uni.uploadfile的onprogressupdate需手动监听并绑定响应式变量,否则进度条不更新;必须用ref/reactive包裹progress值,多文件上传需独立维护状态,安卓端需加兜底定时器。

uni.uploadFile 的 onProgressUpdate 回调必须手动监听
uni.uploadFile 本身不会自动更新 UI,进度条要动起来,全靠你主动监听 onProgressUpdate 并把返回的 progress 值同步到响应式变量里。漏掉这一步,进度条永远卡在 0%。
常见错误是只写了 success 和 fail,却没接 onProgressUpdate;或者监听了但没用 ref 或 reactive 包裹进度值,导致视图不刷新。
- 必须在调用
uni.uploadFile后立刻链式调用uploadTask.onProgressUpdate - 回调参数里的
progress是整数(0–100),直接赋给progressValue即可 - 不要用
setTimeout模拟进度——它和真实上传无关,纯属误导
progress 组件的 percent 必须绑定响应式数据
<progress :percent="currentProgress"></progress> 里的 currentProgress 必须是 ref 或 reactive 创建的响应式变量。写成普通对象属性或局部变量,UI 就不会跟着变。
Vue3 Composition API 下典型写法:
const currentProgress = ref(0)
const uploadTask = uni.uploadFile({ /* ... */ })
uploadTask.onProgressUpdate(res => {
currentProgress.value = res.progress // 注意 .value
})
-
progress属性只接受 0–100 的数字,传字符串或小数会失效 - 如果多个文件同时上传,每个文件需独立维护自己的
progress变量,不能共用一个 - H5 端某些浏览器可能不触发
onProgressUpdate,需降级显示“上传中”文字提示
多图上传时进度状态容易错乱
一次选 5 张图,每张图都走一遍 uni.uploadFile,但如果不为每张图分配唯一标识并隔离状态,进度条就会互相覆盖、跳变甚至显示错位。
关键做法是:把每张图的上传状态封装成对象,用数组管理,渲染时 v-for 绑定各自进度。
- 定义结构如:
{ id: Date.now(), path: 'xxx.jpg', progress: ref(0), status: 'uploading' } - 上传开始前将该对象推入
imageList,后续所有操作(更新进度、标记失败)都基于id查找 - 避免直接用数组索引当 key,尤其在支持删除时,索引会动态变化,导致进度条绑定错乱
安卓真机上进度回调可能延迟或缺失
部分安卓机型(尤其旧版本系统或定制 ROM)对 onProgressUpdate 支持不稳定,表现为:进度跳变(0 → 60 → 100)、长时间无回调、甚至完全不触发。
这不是代码写错了,而是底层 WebView 实现差异。应对策略不是硬等,而是加兜底逻辑:
- 上传开始后启动一个
setInterval,每 300ms 检查是否完成,若未完成且无进度更新,手动递增progress到 95%,最后靠success或fail落地 - 在
fail回调里清除定时器,防止内存泄漏 - 用户感知层面,只要最终结果正确、中间有合理过渡,体验影响有限
真正难处理的是并发上传时的资源争抢和内存占用——图片没压缩就直接上传,大图堆在一起,进度条还没动,App 先卡死了。











