Vue项目实现文件下载进度条功能

 更新时间:2024年03月07日 14:43:30   作者:A 风  
大文件下载,花费的时间比较长,没有任何提示,用户体验很差,需要优化,提示文件在下载中,并且显示进度百分比,下面小编给大家带来了Vue项目实现文件下载进度条功能,感兴趣的朋友一起看看吧

Vue项目实现文件下载进度条

需求场景

大文件下载,花费的时间比较长,没有任何提示,用户体验很差。

需要优化,提示文件在下载中,并且显示进度百分比。

实现步骤

1.下载文件的方法,需要拿到当前进度。

2.每一次下载进度更新,需要监听变化,并且刷新页面显示的数据。

3.封装一个文件下载进度的组件。

下面一步步来实现:

1.获取文件下载进度

axios作为一个易用、简洁且高效的http库,有没有获取下载进度的方法呢?
打开axios官网查看一下,文档中有一个对原生进度事件的处理的方法
onDownloadProgress
允许为下载处理进度事件。
在项目中,我已经对axios进行了封装,并且增加了请求拦截器和响应拦截器。
在封装接口的文件interface.js中,新增一个下载文件,并且获取下载进度的方法。

export const downFileProgress  =(url,parameter,callback,totalSize,uniSign) =>{
  return axios({
    url: url,
    params: parameter,
    method:'get' ,
    responseType: 'blob',
    onDownloadProgress (progress) {
      callback(progress, totalSize, uniSign)
    }
  })
}

2.通过vuex状态管理下载进度

下载进度对象,需要通过vuex状态管理。在store文件下面的modules文件夹中,新建 downLoadProgress.js文件。
用来存放文件下载进度的数组 progressList 和修改进度列表方法,都在这里面。

const state = {
  // 文件下载进度
  progressList: [], 
  progressError: '',
}
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) // 删除进度列表中的进度对象
  },
  CHANGE_SETTING: (state, { key, value }) => {
    // eslint-disable-next-line no-prototype-builtins
    if (state.hasOwnProperty(key)) {
      state[key] = value
    }
  }
}
const actions = {
  changeSetting({ commit }, data) {
    commit('CHANGE_SETTING', data)
  }
}
export default {
  namespaced: true,
  state,
  mutations,
  actions
}

3.新增一个显示进度弹框的组件

<template>
</template>
<script>
  import { mapState } from 'vuex'
  export default {
    name: 'downLoadNotice',
    computed: {
      ...mapState({
      'progressList': state => state.downLoadProgress.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
              if(item.progress)domList.find(i => i.className == item.path).innerHTML = item.progress + '%'
              if (item.progress === null) { // 此处容错处理,如果后端传输文件流报错,删除当前进度对象
                this.$store.commit('downLoadProgress/DEL_PROGRESS', item.path)
                this.$notify.error({
                  title: '错误',
                  message: '文件下载失败!'
                });
              }
            } else {
              // 如果页面中没有该进度对象所对应的弹框,页面新建弹框,并在notify中加入该弹框对象,属性名为该进度对象的path(上文可知path是唯一的),属性值为$notify(element ui中的通知组件)弹框对象
              this.notify[item.path] = this.$notify.success({
                // title: 'info',
                dangerouslyUseHTMLString: true,
                customClass: 'progress-notify',
                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('downLoadProgress/DEL_PROGRESS', item.path)// 删除caseInformation中state的progressList中的进度对象
            }
          })
        },
        deep: true
      }
    }
  }
</script>
<style lang="scss" scoped>
</style>

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

相关文章

  • vue-axios使用详解

    vue-axios使用详解

    本篇文章主要介绍了vue-axios使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • vue实现商城购物车功能

    vue实现商城购物车功能

    这篇文章主要为大家详细介绍了vue实现商城购物车功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Vue中如何优雅的捕获 Promise 异常详解

    Vue中如何优雅的捕获 Promise 异常详解

    这篇文章主要为大家介绍了Vue中如何优雅的捕获 Promise 异常详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • 详解vue-video-player使用心得(兼容m3u8)

    详解vue-video-player使用心得(兼容m3u8)

    这篇文章主要介绍了详解vue-video-player使用心得(兼容m3u8),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • 利用SpringMVC过滤器解决vue跨域请求的问题

    利用SpringMVC过滤器解决vue跨域请求的问题

    下面小编就为大家分享一篇利用SpringMVC过滤器解决vue跨域请求的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • vue源码解析computed多次访问会有死循环原理

    vue源码解析computed多次访问会有死循环原理

    这篇文章主要为大家介绍了vue源码解析computed多次访问会有死循环原理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • vue3使用svg图标的多种方式总结

    vue3使用svg图标的多种方式总结

    svg图片在项目中使用的非常广泛,下面这篇文章主要给大家介绍了关于vue3使用svg图标的多种方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • 浅谈Vuex的状态管理(全家桶)

    浅谈Vuex的状态管理(全家桶)

    本篇文章主要介绍了浅谈Vuex状态管理(全家桶),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Vue实现模糊查询的简单方法实例

    Vue实现模糊查询的简单方法实例

    这篇文章主要给大家介绍了关于Vue实现模糊查询的简单方法,在vue中,前端模糊搜索主要是用computed属性实现,本文通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-08-08
  • 关于vue属性使用和不使用冒号的区别说明

    关于vue属性使用和不使用冒号的区别说明

    这篇文章主要介绍了关于vue属性使用和不使用冒号的区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10

最新评论