最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能

 更新時(shí)間:2021年09月23日 09:41:21   作者:coder__wang  
這篇文章主要介紹了vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能,本文通過(guò)具體實(shí)現(xiàn)代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下

平時(shí)業(yè)務(wù)中下載文件方式常見(jiàn)的有倆種:

第一種,直接訪(fǎng)問(wèn)服務(wù)器的文件地址,自動(dòng)下載文件;

第二種 ,服務(wù)器返回blob文件流,再對(duì)文件流進(jìn)行處理和下載。

一般小文件適用于第一種下載方案,不占用過(guò)多服務(wù)器資源,而對(duì)于體積龐大的文件,常常使用文件流的方式進(jìn)行傳輸,如圖:

文件流傳輸成功后通過(guò)代碼可以立即發(fā)起瀏覽器下載該文件流:

這種方式也有弊端,在文件流傳輸過(guò)程中,用戶(hù)無(wú)法感知文件流的傳輸狀態(tài)(進(jìn)度),會(huì)造成一些困擾(無(wú)法確定當(dāng)前下載操作是否已經(jīng)生效)。針對(duì)這種情況,我們可以在頁(yè)面顯示文件流的狀態(tài)和傳輸進(jìn)度,提高頁(yè)面交互性和友好性。

接下來(lái)是具體實(shí)現(xiàn):

封裝js方法:

/**
 * @param {Object} data: {url: 文件地址, download: 文件名稱(chēng)}
 */
export function downLoadAll(data) {
  let downProgress = {};
  let uniSign = new Date().getTime() + ''; // 可能會(huì)連續(xù)點(diǎn)擊下載多個(gè)文件,這里用時(shí)間戳來(lái)區(qū)分每一次下載的文件
  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對(duì)象中的loaded表示已經(jīng)下載的數(shù)量,total表示總數(shù)量,這里計(jì)算出百分比
      store.commit('caseInformation/SET_PROGRESS', {path: uniSign, 'progress': downProgress}) // 將此次下載的文件名和下載進(jìn)度組成對(duì)象再用vuex狀態(tài)管理
    }}).then( (res)=>{ // 文件流傳輸完成后,開(kāi)啟文件下載
      if(data.downLoad){
        jsFileDownload(res.data,data.downLoad+'.'+data.url.replace(/.+\./,"")); // jsFileDownLoad是用來(lái)下載文件流的,下載插件: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('該文件無(wú)法下載')
  })
}

store中的caseInfomation.js:

...

const state = {
  progressList: [], // 文件下載進(jìn)度列表
  ...
}

const mutations = {
  SET_PROGRESS: (state, progressObj)=>{ // 修改進(jìn)度列表
    if(state.progressList.length){ // 如果進(jìn)度列表存在
      if(state.progressList.find(item=>item.path == progressObj.path)){ // 前面說(shuō)的path時(shí)間戳是唯一存在的,所以如果在進(jìn)度列表中找到當(dāng)前的進(jìn)度對(duì)象
        state.progressList.find(item=>item.path == progressObj.path).progress = progressObj.progress // 改變當(dāng)前進(jìn)度對(duì)象的progress
      }
    }else{
      state.progressList.push(progressObj) // 當(dāng)前進(jìn)度列表為空,沒(méi)有下載任務(wù),直接將該進(jìn)度對(duì)象添加到進(jìn)度數(shù)組內(nèi)
    }
  },
  DEL_PROGRESS: (state, props) => {
    state.progressList.splice(state.progressList.findIndex(item=>item.path == props), 1) // 刪除進(jìn)度列表中的進(jìn)度對(duì)象
  },
  ...
}

頁(yè)面顯示進(jìn)度彈框代碼,downLoadNotice.vue:

<template>

</template>

<script>
  import { mapState } from 'vuex'

  export default {
    name: 'downLoadNotice',
    computed: {
      ...mapState({
      'progressList': state => state.caseInformation.progressList
    })
    },
    data() {
      return {
        notify: {} // 用來(lái)維護(hù)下載文件進(jìn)度彈框?qū)ο?
      }
    },
    watch: { // 監(jiān)聽(tīng)進(jìn)度列表
      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)) { // 如果頁(yè)面已經(jīng)有該進(jìn)度對(duì)象的彈框,則更新它的進(jìn)度progress
              domList.find(i => i.className == item.path).innerHTML = item.progress + '%'
            } else {
              if (item.progress === null) { // 此處容錯(cuò)處理,如果后端傳輸文件流報(bào)錯(cuò),刪除當(dāng)前進(jìn)度對(duì)象
                this.$store.commit('caseInformation/DEL_PROGRESS', item.path)
                return
              }// 如果頁(yè)面中沒(méi)有該進(jìn)度對(duì)象所對(duì)應(yīng)的彈框,頁(yè)面新建彈框,并在notify中加入該彈框?qū)ο?,屬性名為該進(jìn)度對(duì)象的path(上文可知path是唯一的),屬性值為$notify(element ui中的通知組件)彈框?qū)ο?
              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>`, // 顯示下載百分比,類(lèi)名為進(jìn)度對(duì)象的path(便于后面更新進(jìn)度百分比)
                showClose: false,
                duration: 0
              })
            }
            console.log(item.progress + '%', '-------------------------->')

            if (item.progress == 100) { // 如果下載進(jìn)度到了100%,關(guān)閉該彈框,并刪除notify中維護(hù)的彈框?qū)ο?
              this.notify[item.path].close()
              // delete this.notify[item.path] 上面的close()事件是異步的,這里直接刪除會(huì)報(bào)錯(cuò),利用setTimeout,將該操作加入異步隊(duì)列
              setTimeout(() => {
                delete this.notify[item.path]
              }, 1000)
              this.$store.commit('caseInformation/DEL_PROGRESS', item.path)// 刪除caseInformation中state的progressList中的進(jìn)度對(duì)象
            }
          })
        },
        deep: true
      }
    }
  }
</script>

<style scoped>

</style>

以上代碼我們可以封裝到mixins文件夾中,在頁(yè)面內(nèi)用mixins混入:

頁(yè)面中觸發(fā)下載操作:

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

最終頁(yè)面的效果:

最后注意一點(diǎn),以上的下載進(jìn)度并不是真正下載的文件,而是文件流,文件流下載完成后,再通過(guò)上文的js-file-download插件下載真正的文件!

到此這篇關(guān)于vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條的文章就介紹到這了,更多相關(guān)vue文件下載進(jìn)度條內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue設(shè)置代理不起作用問(wèn)題及解決

    vue設(shè)置代理不起作用問(wèn)題及解決

    這篇文章主要介紹了vue設(shè)置代理不起作用問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Vue2?響應(yīng)式系統(tǒng)之異步隊(duì)列

    Vue2?響應(yīng)式系統(tǒng)之異步隊(duì)列

    這篇文章主要介紹了Vue2?響應(yīng)式系統(tǒng)之異步隊(duì)列,文章基于Vue2?的相關(guān)資料展開(kāi)對(duì)主題的詳細(xì)介紹,具有一定的參考價(jià)值需要的小伙伴可以參考一下
    2022-04-04
  • 6種Vue中常用數(shù)據(jù)加密方式的使用詳解

    6種Vue中常用數(shù)據(jù)加密方式的使用詳解

    在Vue.js項(xiàng)目中,你可能需要執(zhí)行數(shù)據(jù)加密以確保敏感信息的安全,這篇文章為大家整理了Vue中常用的6種數(shù)據(jù)加密方式的使用,需要的小伙伴可以參考下
    2024-03-03
  • Vue路由管理器Vue-router的使用方法詳解

    Vue路由管理器Vue-router的使用方法詳解

    本文將詳細(xì)介紹Vue路由管理器Vue-router的使用方法詳解,需要的朋友可以參考下
    2020-02-02
  • 淺談mint-ui loadmore組件注意的問(wèn)題

    淺談mint-ui loadmore組件注意的問(wèn)題

    下面小編就為大家?guī)?lái)一篇淺談mint-ui loadmore組件注意的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Vue動(dòng)態(tài)組件?component?:is的使用代碼示范

    Vue動(dòng)態(tài)組件?component?:is的使用代碼示范

    vue?動(dòng)態(tài)組件用于實(shí)現(xiàn)在指定位置上,動(dòng)態(tài)加載不同的組件,這篇文章主要介紹了Vue動(dòng)態(tài)組件?component?:is的使用,需要的朋友可以參考下
    2023-09-09
  • 詳解打造 Vue.js 可復(fù)用組件

    詳解打造 Vue.js 可復(fù)用組件

    Vue.js 是一套構(gòu)建用戶(hù)界面的漸進(jìn)式框架。我們可以使用簡(jiǎn)單的 API 來(lái)實(shí)現(xiàn)響應(yīng)式的數(shù)據(jù)綁定和組合的視圖組件。
    2017-03-03
  • Vue無(wú)法訪(fǎng)問(wèn).env.development定義的變量值問(wèn)題及解決

    Vue無(wú)法訪(fǎng)問(wèn).env.development定義的變量值問(wèn)題及解決

    這篇文章主要介紹了Vue無(wú)法訪(fǎng)問(wèn).env.development定義的變量值問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • vue3 Composition API使用示例教程

    vue3 Composition API使用示例教程

    Vue3新增了Composition API,我們只需將實(shí)現(xiàn)某一功能的相關(guān)代碼全部放進(jìn)一個(gè)函數(shù)中,然后return需要對(duì)外暴露的對(duì)象,這篇文章主要介紹了vue3 Composition API使用,需要的朋友可以參考下
    2022-12-12
  • vue實(shí)現(xiàn)的微信機(jī)器人聊天功能案例【附源碼下載】

    vue實(shí)現(xiàn)的微信機(jī)器人聊天功能案例【附源碼下載】

    這篇文章主要介紹了vue實(shí)現(xiàn)的微信機(jī)器人聊天功能,結(jié)合實(shí)例形式分析了基于vue.js的微信機(jī)器人聊天相關(guān)界面布局、ajax交互等操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下
    2019-02-02

最新評(píng)論

东莞市| 新宁县| 玉林市| 麟游县| 夹江县| 张家港市| 奎屯市| 永康市| 宝丰县| 武陟县| 宝丰县| 柏乡县| 江孜县| 进贤县| 宁津县| 仙桃市| 秀山| 北安市| 驻马店市| 镇远县| 横峰县| 龙井市| 富裕县| 阿城市| 陵水| 石林| 娱乐| 灵璧县| 汕头市| 峨眉山市| 和田市| 宣化县| 霍邱县| 芷江| 连云港市| 永春县| 儋州市| 广汉市| 保靖县| 丹江口市| 金山区|