vue前端实现下载进度
实现下载进度条的基本思路
在Vue中实现下载进度条,通常需要结合XMLHttpRequest或Fetch API来监听下载进度事件。通过计算已下载数据与总数据的比例,动态更新进度条的显示。
使用XMLHttpRequest监听进度
XMLHttpRequest提供了progress事件,可以获取下载的进度信息。创建一个XMLHttpRequest实例,设置事件监听器来更新进度。
// 在Vue组件的方法中
downloadFile() {
const xhr = new XMLHttpRequest();
xhr.open('GET', '文件下载地址', true);
xhr.responseType = 'blob';
xhr.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percent = (event.loaded / event.total) * 100;
this.progress = Math.round(percent); // 更新Vue的progress数据
}
});
xhr.onload = () => {
if (xhr.status === 200) {
const blob = new Blob([xhr.response]);
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = '文件名';
link.click();
}
};
xhr.send();
}
使用Fetch API实现进度
Fetch API本身不直接支持进度事件,但可以通过响应体的body.getReader()方法手动计算进度。
async downloadFileWithFetch() {
const response = await fetch('文件下载地址');
const reader = response.body.getReader();
const contentLength = +response.headers.get('Content-Length');
let receivedLength = 0;
let chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
receivedLength += value.length;
this.progress = Math.round((receivedLength / contentLength) * 100);
}
const blob = new Blob(chunks);
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = '文件名';
link.click();
}
进度条UI实现
在Vue模板中,可以使用<progress>元素或自定义样式来显示进度。
<template>
<div>
<button @click="downloadFile">下载文件</button>
<progress :value="progress" max="100"></progress>
<span>{{ progress }}%</span>
</div>
</template>
处理大文件分块下载
对于大文件,可以分块下载并合并,避免内存问题。使用Blob和URL.createObjectURL将分块数据合并为完整文件。
// 分块下载示例
downloadChunks() {
const chunkSize = 1024 * 1024; // 1MB
let chunks = [];
let received = 0;
const downloadNextChunk = async (start) => {
const end = start + chunkSize - 1;
const response = await fetch('文件下载地址', {
headers: { 'Range': `bytes=${start}-${end}` }
});
const blob = await response.blob();
chunks.push(blob);
received += blob.size;
this.progress = Math.round((received / totalSize) * 100);
if (received < totalSize) {
downloadNextChunk(start + chunkSize);
} else {
this.mergeChunks(chunks);
}
};
downloadNextChunk(0);
}
mergeChunks(chunks) {
const blob = new Blob(chunks);
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = '文件名';
link.click();
}
错误处理与用户体验
添加错误处理逻辑,确保下载失败时用户得到反馈。可以在XMLHttpRequest或Fetch的catch中处理错误。
xhr.onerror = () => {
this.error = '下载失败,请重试';
};
使用第三方库简化实现
如果需要更简单的实现,可以考虑使用axios库,它内置了进度事件支持。
axios({
url: '文件下载地址',
method: 'GET',
responseType: 'blob',
onDownloadProgress: (progressEvent) => {
const percent = (progressEvent.loaded / progressEvent.total) * 100;
this.progress = Math.round(percent);
}
}).then(response => {
const blob = new Blob([response.data]);
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = '文件名';
link.click();
});
总结
通过XMLHttpRequest或Fetch API监听下载进度,结合Vue的数据绑定特性,可以轻松实现下载进度条功能。分块下载适用于大文件,而第三方库如axios能进一步简化代码。







