一、实现效果
二、实现方式
方案:使用axios方法onDownloadProgress方法监听下载进度
使用此方式的前提!!!请让后端在响应头中加上content-length
,存放下载文件的总大小,如下图:
三、代码
1、进度条页面代码如下:
<Spin fix v-if="spinVisible">
<Icon type="ios-loading" size=18 class="demo-spin-icon-load"></Icon>
<div>正在下载代码,请稍后...</div>
<el-progress :percentage="percentComplete"></el-progress>
</Spin>
ps:我的进度条是在iview组件spin加载页里的,若你不需要,可只粘贴el-progress组件部分
2、点击下载按钮的js方法逻辑部分
在Axios
中,onDownloadProgress
是一个回调函数,它作为参数传递给axios
方法。当axios
开始接收响应数据时,会定期触发该回调函数,以提供下载进度信息。
onDownloadProgress
回调函数的参数包含以下信息:
- lengthComputable:一个布尔值,指示是否可以根据已接收的字节数和总字节数计算出下载进度百分比。
- loaded:一个表示已接收字节数的整数,表示当前已下载的字节数。
- total:一个表示总字节数的整数,表示要下载的文件的总字节数。如果lengthComputable为false,那么total的值将为0。
// 点击下载代码的方法
downloadCode(id) {
// 定义全局变量percentComplete 为下载进度值(定义data此处忽略)
this.percentComplete = 0
// axios调用下载接口,timeout可删掉,我这里是因为文件太大想延长请求时间
axios({method: 'post',url: ‘xxxx’,data: xxx,
headers: { 'Authorization': Cookies.get('token') }, responseType: 'blob', timeout: 600000,
// withCredentials: true,可配可不配,根据项目实际情况选择
// 使用此方法监听
onDownloadProgress: (e) => {
console.log('e:',e);
// e是一个包含下载进度信息的事件对象,其中包括loaded 、total属性:
this.percentComplete = Math.floor((e.loaded / e.total) * 100)
} })
.then((res) => {
const blob = new Blob([res.data], {type: 'application/octet-stream'}); //处理文档流
const fileName = res.headers['content-disposition'].split('filename=')[1];
const elink = document.createElement("a");
elink.download = fileName;
elink.style.display = "none";
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
}).finally(() => {
this.spinVisible = false
});
},
以上,便可以实现一个下载进度条监听的功能,
其实还是踩了很多坑的,什么XHR等等,经过实验,以上方法就可以简便实现功能。
希望能帮助到你~