vue项目实现文件下载进度条
平时业务中下载文件方式常见的有俩种:
第一种,直接访问服务器的文件地址,自动下载文件;
第二种 ,服务器返回blob文件流,再对文件流进行处理和下载。
一般小文件适用于第一种下载方案,不占用过多服务器资源,而对于体积庞大的文件,常常使用文件流的方式进行传输,如图:

文件流传输成功后通过代码可以立即发起浏览器下载该文件流:

这种方式也有弊端,在文件流传输过程中,用户无法感知文件流的传输状态(进度),会造成一些困扰(无法确定当前下载操作是否已经生效)。针对这种情况,我们可以在页面显示文件流的状态和传输进度,提高页面交互性和友好性。
接下来是具体实现:
封装js方法:
/**
* @param {Object} data: {url: 文件地址, download: 文件名称}
*/
export function downLoadAll(data) {
let downProgress = {};
let uniSign = new Date().getTime() + ''; // 可能会连续点击下载多个文件,这里用时间戳来区分每一次下载的文件
axios.get(
data.url,
{ responseType: 'blob', headers: { "Content-Type": "application/json; charset=utf-8" },
onDownloadProgress (progress) {
downProgress = Math.round(100 * progress.loaded / progress.total) // progress对象中的loaded表示已经下载的数量,total表示总数量,这里计算出百分比
store.commit('caseInformation/SET_PROGRESS', {path: uniSign, 'progress': downProgress}) // 将此次下载的文件名和下载进度组成对象再用vuex状态管理
}}).then( (res)=>{ // 文件流传输完成后,开启文件下载
if(data.downLoad){
jsFileDownload(res.data,data.downLoad+'.'+data.url.replace(/.+\./,"")); // jsFileDownLoad是用来下载文件流的,下载插件:npm i js-file-download,import引入:import jsFileDownLoad from 'js-file-download'
} else {
jsFileDownload(res.data, data.url.split('/')[data.url.split('/').length-1]);
}
}).catch((e)=>{
this.$message.error('该文件无法下载')
})
}
store中的caseInfomation.js:
...
const state = {
progressList: [], // 文件下载进度列表
...
}
const mutations = {
SET_PROGRESS: (state, progressObj)=>{ // 修改进度列表
if(state.progressList.length){ // 如果进度列表存在
if(state.progressList.find(item=>item.path == progressObj.path)){ // 前面说的path时间戳是唯一存在的,所以如果在进度列表中找到当前的进度对象
state.progressList.find(item=>item.path == progressObj.path).progress = progressObj.progress // 改变当前进度对象的progress
}
}else{
state.progressList.push(progressObj) // 当前进度列表为空,没有下载任务,直接将该进度对象添加到进度数组内
}
},
DEL_PROGRESS: (state, props) => {
state.progressList.splice(state.progressList.findIndex(item=>item.path == props), 1) // 删除进度列表中的进度对象
},
...
}
页面显示进度弹框代码,downLoadNotice.vue:
<template> </template> <script>
import { mapState } from 'vuex' export default {
name: 'downLoadNotice',
computed: {
...mapState({
'progressList': state => state.caseInformation.progressList
})
},
data() {
return {
notify: {} // 用来维护下载文件进度弹框对象
}
},
watch: { // 监听进度列表
progressList: {
handler(n) {
let data = JSON.parse(JSON.stringify(n))
data.forEach(item => {
const domList = [...document.getElementsByClassName(item.path)]
if (domList.find(i => i.className == item.path)) { // 如果页面已经有该进度对象的弹框,则更新它的进度progress
domList.find(i => i.className == item.path).innerHTML = item.progress + '%'
} else {
if (item.progress === null) { // 此处容错处理,如果后端传输文件流报错,删除当前进度对象
this.$store.commit('caseInformation/DEL_PROGRESS', item.path)
return
}// 如果页面中没有该进度对象所对应的弹框,页面新建弹框,并在notify中加入该弹框对象,属性名为该进度对象的path(上文可知path是唯一的),属性值为$notify(element ui中的通知组件)弹框对象
this.notify[item.path] = this.$notify.success({
// title: 'Info',
dangerouslyUseHTMLString: true,
message: `<p style="width: 100px;">正在下载<span class="${item.path}" style="float: right">${item.progress}%</span></p>`, // 显示下载百分比,类名为进度对象的path(便于后面更新进度百分比)
showClose: false,
duration: 0
})
}
console.log(item.progress + '%', '-------------------------->') if (item.progress == 100) { // 如果下载进度到了100%,关闭该弹框,并删除notify中维护的弹框对象
this.notify[item.path].close()
// delete this.notify[item.path] 上面的close()事件是异步的,这里直接删除会报错,利用setTimeout,将该操作加入异步队列
setTimeout(() => {
delete this.notify[item.path]
}, 1000)
this.$store.commit('caseInformation/DEL_PROGRESS', item.path)// 删除caseInformation中state的progressList中的进度对象
}
})
},
deep: true
}
}
}
</script> <style scoped> </style>
以上代码我们可以封装到mixins文件夹中,在页面内用mixins混入:

页面中触发下载操作:
downLoad(item){
let downData = {
url: `ipdoc${item.url}`,
downLoad: item.fileName
}
this.$commonUtils.downLoadAll(downData) // 下载
},
最终页面的效果:

最后注意一点,以上的下载进度并不是真正下载的文件,而是文件流,文件流下载完成后,再通过上文的js-file-download插件下载真正的文件!
脚踏实地行,海阔天空飞
vue项目实现文件下载进度条的更多相关文章
- Python展示文件下载进度条
前言 大家在用Python写一些小程序的时候,经常都会用到文件下载,对于一些较小的文件,大家可能不太在乎文件的下载进度,因为一会就下载完毕了. 但是当文件较大,比如下载chromedriver的时候, ...
- H5+Ajax+WebApi实现文件下载(进度条,多文件)
前言 踩过的坑 1.WebAPI跨域 2.Jquery ajax低版本不支持XHR 2功能 3.Jquery ajax不支持Deferred的process事件 4.IE下文件名乱码问题 功能实现 & ...
- js 文件下载 进度条
js: /** * 下载文件 - 带进度监控 * @param url: 文件请求路径 * @param params: 请求参数 * @param name: 保存的文件名 * @param pro ...
- 【python 】文件下载进度条(装逼利器)
基础版 import requests url = "http://mp.111ttt.cn/mp3free/81135985.mp3" rsp = requests.get(ur ...
- vue 圆形进度条组件解析
项目简介 本组件是vue下的圆形进度条动画组件 自由可定制,几乎全部参数均可设置 源码简单清晰 面向人群 急于使用vue圆形进度条动画组件的同学.直接下载文件,拷贝代码即可运行. 喜欢看源码,希望了解 ...
- 居于Web的进度条实现思路(下载百分比)
http://www.cnblogs.com/wfyfngu/p/4866434.html 在传统桌面项目中,进度条随处可见,但作为一个很好的用户体验,却没有在如今主流的B/S程序中得到传承,不能不说 ...
- 如何在Vue项目中给路由跳转加上进度条
1.前言 在平常浏览网页时,我们会注意到在有的网站中,当点击页面中的链接进行路由跳转时,页面顶部会有一个进度条,用来标示页面跳转的进度(如下图所示).虽然实际用处不大,但是对用户来说,有个进度条会大大 ...
- Vue项目开发,nprogress进度条加载之超详细讲解及实战案例
Nprogress的默认进度条很细,它的设计灵感主要来源于 谷歌,YouTube 他的安装方式也很简单,你可以有两种使用方式: 直接引入js和css文件 使用npm安装的的方式 直接引入: Npm安装 ...
- vue项目上传文件以及进度条
最近做项目的时候,需要上传自定义镜像.并且附带进度条,上网查询一下资料,经过一番折磨,也总算做出来了,把自己写项目的内容给大家分享一下. 先直接贴代码吧 1.首先声明一个formData对象. 2.把 ...
随机推荐
- 寻找写代码感觉(一)之使用 Spring Boot 快速搭建项目
写在前面 现在已经是八月份了,我已经荒废了半年居多,不得不说谈恋爱确实是个麻烦的事,谈好了皆大欢喜,分手了就是萎靡不振,需要很长一段时间才能缓过来. 人还是要有梦想的,至于实现只不过是一个契机,但凡不 ...
- vim编辑文件时[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
出现这个问题是因为你上次编辑的时候在没有保存的情况下退出了(如:电脑关机等)也有可能是有其他人在和你同时进行编辑行为(不同会话中).这是因为在用vim编辑的时候,vim会在打开文件目录下 ...
- 痞子衡嵌入式:i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项. 最近痞子衡在支持一个印度客户,这个客户项目主芯片选择 ...
- vue--三种组件中之间的传值
参考网址:https://www.jianshu.com/p/46573a741c29 一.父子组件之间的传值----props/$emit 组件之间的传值,我们比较常用到的是props/$emit ...
- beeline: 新版连接Hive server的工具
HiveServer2 支持一个新的命令行Shell,称为Beeline,它是基于SQLLine CLI的JDBC客户端.它是从 Hive 0.11版本引入的,是Hive新的命令行客户端工具.Hive ...
- 【springcloud】springcloud与springboot的版本对应关系
官方网址:https://start.spring.io/actuator/info 更新时间:2019-12-01 spring-cloud: "Finchley.M2": &q ...
- 进程上下文&中断上下文
文章出自http://hi.baidu.com/bkhcvzdvmjfkpyr/item/5444001fa68d065bf1090ea6 处理器总处于以下状态中的一种: 1.内核态,运行于进程上下文 ...
- Java String 综述(上篇)
摘要: Java 中的 String类 是我们日常开发中使用最为频繁的一个类,但要想真正掌握的这个类却不是一件容易的事情.笔者为了还原String类的真实全貌,先分为上.下两篇博文来综述Java中的S ...
- 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建一个版本
我们可以使用官方 sentry-cli 工具操作 Sentry API,从而来为你的项目管理一些数据.它主要用于管理 iOS.Android 的调试信息文件,以及其他平台的版本(release)和源代 ...
- 微信支付 调用支付jsapi缺少参数total_fee 和 支付验证签名失败 prepay_id配置问题
=======================================================先熟悉一下统一下单api所需要的参数=========================== ...