Vue文件下載進(jìn)度條的實(shí)現(xiàn)過程
需求場(chǎng)景:
1、大文件壓縮過后依舊很大,接口返回response速度過慢,頁(yè)面沒有任何顯示,體驗(yàn)太差。
2、需要在瀏覽器顯示正在加載中的狀態(tài)優(yōu)化顯示,提高用戶體驗(yàn)
實(shí)現(xiàn)原理:
1、使用onDownloadProgress方法API獲取進(jìn)度及文件大小等數(shù)據(jù)
2、mixin混入實(shí)現(xiàn)監(jiān)聽進(jìn)度條進(jìn)度
3、vuex修改進(jìn)度條進(jìn)度
優(yōu)化過程:
使用onDownloadProgress封裝一個(gè)下載文件的方法
downFileProgress: function (url, params, headers, blenderApiUrl, callback, uniSign) {
return axios({
url: url,
params: params,
method: 'get',
responseType: 'blob',
baseURL: blenderApiUrl,
headers: headers,
onDownloadProgress (progress) {
callback(progress, uniSign)
}
})
}在下載文件的地方,使用封裝的方法downFileProgress
downOrgFile (row) {
let uniSign = `${new Date().getTime()} ` // 可能會(huì)連續(xù)點(diǎn)擊下載多個(gè)文件,這里用時(shí)間戳來區(qū)分每一次下載的文件
const url = `${this.$api.LifeInsuranceScenario2DownFile}/${row.account_name}/${row.task_id}`
const baseUrl = this.iframeData.blenderApiUrl
this.$http.downFileProgress(url, {}, this.headers, baseUrl, this.callBackProgress, uniSign).then(res => {
if (!res) {
this.$sweetAlert.errorWithTimer('文件下載失?。?)
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([res.data]), '中間項(xiàng)下載.zip')
} else {
let url = window.URL.createObjectURL(new Blob([res.data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', 'xxx.zip')
document.body.appendChild(link)
link.click()
link.remove()
}
})
},
callBackProgress (progress, uniSign) {
let total = progress.srcElement.getResponseHeader('Real-Content-Length')
// progress對(duì)象中的loaded表示已經(jīng)下載的數(shù)量,total表示總數(shù)量,這里計(jì)算出百分比
let downProgress = Math.floor((progress.loaded / total) * 100)
// 將此次下載的文件名和下載進(jìn)度組成對(duì)象再用vuex狀態(tài)管理
this.$store.commit('SET_PROGRESS', { path: uniSign, progress: downProgress })
}創(chuàng)建component同等級(jí)mixin文件夾,文件夾創(chuàng)建index.js
import { mapState } from 'vuex'
export const mixins = {
computed: {
...mapState({
progressList: state => state.progressList
})
},
data () {
return {
notify: {} // 用來維護(hù)下載文件進(jìn)度彈框?qū)ο?
}
},
watch: {
// 監(jiān)聽進(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
if (item.progress) domList.find(i => i.className === item.path).innerHTML = item.progress + '%'
if (item.progress === null) {
// 此處容錯(cuò)處理,如果后端傳輸文件流報(bào)錯(cuò),刪除當(dāng)前進(jìn)度對(duì)象
this.$store.commit('DEL_PROGRESS', item.path)
this.$notify.error({ title: '錯(cuò)誤', message: '文件下載失??!' })
}
} else {
// 如果頁(yè)面中沒有該進(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({
dangerouslyUseHTMLString: true,
customClass: 'progress-notify',
message: `<p style="width: 150px;line-height: 13px;">中間項(xiàng)正在下載<span class="${item.path}" style="float: right">${item.progress}%</span></p>`, // 顯示下載百分比,類名為進(jìn)度對(duì)象的path(便于后面更新進(jìn)度百分比)
showClose: true,
duration: 0
})
}
if (item.progress === 100) {
// 如果下載進(jìn)度到了100%,關(guān)閉該彈框,并刪除notify中維護(hù)的彈框?qū)ο?
// this.notify[item.path].close()
// 上面的close()事件是異步的,直接delete this.notify[item.path]會(huì)報(bào)錯(cuò),利用setTimeout,將該操作加入異步隊(duì)列
setTimeout(() => {
delete this.notify[item.path]
}, 1000)
this.$store.commit('DEL_PROGRESS', item.path) // 刪除caseInformation中state的progressList中的進(jìn)度對(duì)象
}
})
},
deep: true
}
}
}
下載方法的組件引入mixin
import { mixins } from '../mixin/index'
export default {
mixins: [mixins],
......
}Vuex配置進(jìn)度條
const state = {
progressList: []
}
export default stateconst mutations = {
SET_PROGRESS: (state, progressObj) => {
// 修改進(jìn)度列表
if (state.progressList.length) {
// 如果進(jìn)度列表存在
if (state.progressList.find(item => item.path === progressObj.path)) {
// 前面說的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 {
// 當(dāng)前進(jìn)度列表為空,沒有下載任務(wù),直接將該進(jìn)度對(duì)象添加到進(jìn)度數(shù)組內(nèi)
state.progressList.push(progressObj)
}
},
DEL_PROGRESS: (state, props) => {
state.progressList.splice(state.progressList.findIndex(item => item.path === props), 1) // 刪除進(jìn)度列表中的進(jìn)度對(duì)象
},
CHANGE_SETTING: (state, { key, value }) => {
// eslint-disable-next-line no-prototype-builtins
if (state.hasOwnProperty(key)) {
state[key] = value
}
}
}
export default mutations
export const getProgressList = state => state.progressList
export const changeSetting = function ({ commit }, data) {
commit('CHANGE_SETTING', data)
}
export const setprogress = function ({ commit }, data) {
commit('SET_PROGRESS', data)
}
export const delprogress = function ({ commit }, data) {
commit('DEL_PROGRESS', data)
}最終效果圖

參考文章:
到此這篇關(guān)于Vue文件下載進(jìn)度條的實(shí)現(xiàn)過程的文章就介紹到這了,更多相關(guān)Vue下載進(jìn)度條內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue使用Echarts實(shí)現(xiàn)排行榜效果
這篇文章主要為大家詳細(xì)介紹了Vue使用Echarts實(shí)現(xiàn)排行榜效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
electron+vue實(shí)現(xiàn)div contenteditable截圖功能
這篇文章主要介紹了electron+vue實(shí)現(xiàn)div contenteditable截圖功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
vue結(jié)合leaflet實(shí)現(xiàn)熱力圖
本文主要介紹了vue實(shí)現(xiàn)熱力圖,結(jié)合leaflet.heat插件可以很容易的做出熱力圖,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
使用vue完成微信公眾號(hào)網(wǎng)頁(yè)小記(推薦)
公司最近有一個(gè)H5頁(yè)面的功能,比較簡(jiǎn)單的一個(gè)調(diào)查表功能,嵌套在我們微信公眾號(hào)里面。這篇文章主要介紹了使用vue完成微信公眾號(hào)網(wǎng)頁(yè)小記,需要的朋友可以參考下2019-04-04
vue實(shí)現(xiàn)圖片轉(zhuǎn)pdf的示例代碼
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)圖片轉(zhuǎn)pdf的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以跟隨小編一起了解一下2023-08-08
詳解Vue ElementUI手動(dòng)上傳excel文件到服務(wù)器
這篇文章主要介紹了詳解Vue ElementUI手動(dòng)上傳excel文件到服務(wù)器,對(duì)ElementUI感興趣的同學(xué),可以參考下2021-05-05
Vue項(xiàng)目通過vue-i18n實(shí)現(xiàn)國(guó)際化方案(推薦)
這篇文章主要介紹了Vue項(xiàng)目通過vue-i18n實(shí)現(xiàn)國(guó)際化方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12
Vue 實(shí)現(xiàn)可視化拖拽頁(yè)面編輯器
這篇文章主要介紹了Vue 實(shí)現(xiàn)可視化拖拽頁(yè)面編輯器的方法,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下2021-02-02

