Vue 文件上传下载进度监听核心是利用 XMLHttpRequest 的 upload/download.onprogress 事件,通过 Axios 的 onUploadProgress/onDownloadProgress 回调封装统一进度管理器,支持多任务、可中断、响应式更新,并需处理 total 为 0、小文件闪烁、网络中断等边界情况。

Vue 中封装文件上传与下载进度监听,核心在于利用原生 XMLHttpRequest 的 upload.onprogress 和 download.onprogress 事件,并通过统一的请求工具(如 Axios)暴露回调入口,再结合响应式数据驱动 UI 更新。关键不是“写个函数”,而是建立可复用、可中断、可追踪多任务的监听机制。
上传进度:基于 Axios 的 onUploadProgress 封装
Axios 支持在配置中传入 onUploadProgress 回调,它接收原生 ProgressEvent,从中可提取已传输字节数(loaded)和总大小(total):
- 封装时建议将进度计算逻辑内聚,避免每次手动算百分比;例如统一返回
{ percent: number, loaded: number, total: number, speed: number } - 支持单文件与多文件场景:为每个文件生成唯一 ID(如用
Symbol()或Math.random()),把进度存入 Map 或响应式对象,便于组件按需绑定 - 注意:若使用
FormData且含多个字段,total可能包含非文件内容,实际进度应以文件本体大小为基准(可提前file.size记录)
下载进度:用 responseType: 'blob' + onDownloadProgress
浏览器原生不直接暴露下载流进度,但 Axios 的 onDownloadProgress 在 responseType: 'blob' 模式下可用,原理同上传:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 必须设置
responseType: 'blob',否则onDownloadProgress不触发 - 进度值同样来自
ProgressEvent,但部分浏览器(如旧版 Safari)可能不支持或返回total === 0;需降级处理:当total === 0时,用“加载中…”代替百分比 - 下载完成后需用
URL.createObjectURL(blob)触发下载,或借助js-file-download等轻量库自动处理文件名与 MIME 类型
统一进度管理器:解耦业务与监听逻辑
避免每个组件重复写进度更新逻辑,可抽离一个进度管理器(如 useUploadProgress Composable):
立即学习“前端免费学习笔记(深入)”;
- 内部维护
Map<string ref>></string>存储各任务进度,key 为任务 ID - 提供
startUpload(file, options)方法,返回 Promise 并自动注册进度监听 - 支持取消:调用
AbortController中断请求,同时从 Map 中清理对应进度项 - 配合 Pinia/Vuex 存储全局下载队列状态,方便在多个页面共享进度(如顶部全局进度条)
异常与边界情况处理
进度监听不是“开了就稳”,需主动兜底:
- 网络中断或服务端超时:
onUploadProgress停止触发,但 Promise 未 reject —— 应设置超时时间 + 主动轮询readyState状态 - 小文件(setTimeout(() => showProgress, 100))防止闪烁
- 跨域请求需服务端明确返回
Access-Control-Allow-Headers: Range才支持分块续传,否则进度可能不准

















