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:





以上代码我们可以封装到mixins文件夹中,在页面内用mixins混入:

vue项目实现文件下载进度条功能_第1张图片

页面中触发下载操作:

downLoad(item){
   let downData = {
      url: `ipdoc${item.url}`,
      downLoad: item.fileName
   }
   this.$commonUtils.downLoadAll(downData) // 下载
},

最终页面的效果:

vue项目实现文件下载进度条功能_第2张图片

最后注意一点,以上的下载进度并不是真正下载的文件,而是文件流,文件流下载完成后,再通过上文的js-file-download插件下载真正的文件!

到此这篇关于vue项目实现文件下载进度条的文章就介绍到这了,更多相关vue文件下载进度条内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

你可能感兴趣的