VueJS中如何让上传进度条匀速从1%递增至100%
实现Vue中Axios上传的匀速进度条
问题根源
你原来的代码里给progressEvent.total加了10000000,这会导致计算的百分比在上传初期被刻意压低,但当文件快传完时,loaded接近真实total,此时计算出的百分比会突然飙升到接近100%。另外,真实的上传进度本身受网络、服务器处理速度影响,不可能是匀速的,所以直接基于真实进度更新视图做不到视觉上的匀速效果。
解决方案:模拟匀速进度 + 真实进度兜底
要实现从1%开始匀速递增到100%的视觉效果,我们需要用定时器模拟匀速增长的进度,同时监听真实上传进度,确保模拟进度不会超过真实进度,最后在上传完成时将进度直接拉到100%。
1. 在Vue组件中添加必要的状态变量
在组件的data里定义以下变量:
data() { return { uploadPercentage: [], // 你的原有进度数组 realProgress: 0, // 记录真实的上传进度 simulatedProgress: 0, // 模拟的进度值 progressTimer: null, // 定时器实例,用于清除定时器 progress_index: 0 // 你的原有索引变量 } }
2. 修改Axios的onUploadProgress回调
这个回调只负责更新真实进度,不直接更新视图:
onUploadProgress: function(progressEvent) { // 计算真实进度,避免除以0的情况 if (progressEvent.total > 0) { this.realProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total); } }.bind(this)
3. 添加模拟进度的方法
写一个方法来启动匀速进度的模拟:
methods: { startSimulatedProgress() { // 初始化模拟进度为1% this.simulatedProgress = 1; this.uploadPercentage[this.progress_index] = 1; // 每隔50ms增加一次进度(可根据需求调整间隔) this.progressTimer = setInterval(() => { // 模拟进度不能超过真实进度,也不能超过99%(留最后一步到100%) if (this.simulatedProgress < Math.min(this.realProgress, 99)) { // 每次增加1%,可调整步长控制速度 this.simulatedProgress += 1; this.uploadPercentage[this.progress_index] = this.simulatedProgress; } }, 50); }, // 结束模拟进度,将进度设为100% endSimulatedProgress() { clearInterval(this.progressTimer); this.simulatedProgress = 100; this.realProgress = 100; this.uploadPercentage[this.progress_index] = 100; } }
4. 整合到上传流程中
在触发上传的方法里,先启动模拟进度,上传完成/失败时结束模拟:
uploadFile() { // 初始化状态 this.realProgress = 0; this.simulatedProgress = 0; this.startSimulatedProgress(); axios.post('/your-upload-url', formData, { onUploadProgress: this.onUploadProgress // 用上面修改后的回调 }) .then(() => { this.endSimulatedProgress(); // 其他上传成功逻辑 }) .catch(() => { this.endSimulatedProgress(); // 其他上传失败逻辑 }); }
说明
- 你可以调整
setInterval的间隔(比如改成100ms)和每次增加的步长(比如改成0.5)来控制进度条的速度。 - 模拟进度被限制在不超过真实进度,避免出现“进度条走完但文件还没传完”的尴尬情况。
- 上传完成时直接把进度设为100%,确保最终状态正确。
内容的提问来源于stack exchange,提问作者Syed Zaeem
相关产品推荐
相关产品推荐

