vue前端实现下载进度
Vue 前端实现下载进度的方法
使用 axios 的 onDownloadProgress 回调
在 axios 请求中,可以通过 onDownloadProgress 回调函数实时获取下载进度。该回调会提供一个事件对象,包含 loaded(已下载字节)和 total(总字节)属性。
axios.get('/file-url', {
responseType: 'blob',
onDownloadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(percentCompleted + '%');
}
}).then(response => {
// 处理下载完成后的逻辑
});
结合 Vue 的响应式数据更新进度条
将进度数据绑定到 Vue 的 data 中,通过模板或计算属性实时显示进度条。
export default {
data() {
return {
downloadProgress: 0
};
},
methods: {
downloadFile() {
axios.get('/file-url', {
responseType: 'blob',
onDownloadProgress: (progressEvent) => {
this.downloadProgress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
}
}).then(response => {
// 创建下载链接
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'filename.ext');
document.body.appendChild(link);
link.click();
});
}
}
};
使用进度条组件
结合 UI 框架(如 Element UI、Ant Design Vue)的进度条组件,实现可视化效果。
<template>
<div>
<el-progress :percentage="downloadProgress"></el-progress>
<button @click="downloadFile">下载文件</button>
</div>
</template>
处理跨域和分块下载
对于大文件或分块下载,需确保服务器支持 Content-Length 头信息。若服务器未返回 total,需手动计算或分块处理。
onDownloadProgress: (progressEvent) => {
if (progressEvent.lengthComputable) {
this.downloadProgress = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
} else {
// 无法计算总大小时的备选方案
this.downloadProgress = Math.round(
(progressEvent.loaded / estimatedTotal) * 100
);
}
}
使用 Fetch API 替代方案
若未使用 axios,可通过 Fetch API 的 ReadableStream 实现类似功能。
fetch('/file-url')
.then(response => {
const reader = response.body.getReader();
const contentLength = +response.headers.get('Content-Length');
let receivedLength = 0;
return new Promise((resolve) => {
function processChunk({ done, value }) {
if (done) {
resolve(new Blob([chunks]));
return;
}
chunks.push(value);
receivedLength += value.length;
this.downloadProgress = Math.round((receivedLength / contentLength) * 100);
return reader.read().then(processChunk);
}
return reader.read().then(processChunk);
});
});
注意事项
- 确保服务器正确返回
Content-Length头,否则total可能为 0。 - 进度计算需处理
lengthComputable为false的情况。 - 大文件下载建议使用分块或流式处理,避免内存问题。







