Vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能
Vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條
需求場(chǎng)景
大文件下載,花費(fèi)的時(shí)間比較長(zhǎng),沒(méi)有任何提示,用戶(hù)體驗(yàn)很差。
需要優(yōu)化,提示文件在下載中,并且顯示進(jìn)度百分比。
實(shí)現(xiàn)步驟
1.下載文件的方法,需要拿到當(dāng)前進(jìn)度。
2.每一次下載進(jìn)度更新,需要監(jiān)聽(tīng)變化,并且刷新頁(yè)面顯示的數(shù)據(jù)。
3.封裝一個(gè)文件下載進(jìn)度的組件。
下面一步步來(lái)實(shí)現(xiàn):
1.獲取文件下載進(jìn)度
axios作為一個(gè)易用、簡(jiǎn)潔且高效的http庫(kù),有沒(méi)有獲取下載進(jìn)度的方法呢?
打開(kāi)axios官網(wǎng)查看一下,文檔中有一個(gè)對(duì)原生進(jìn)度事件的處理的方法
onDownloadProgress
允許為下載處理進(jìn)度事件。
在項(xiàng)目中,我已經(jīng)對(duì)axios進(jìn)行了封裝,并且增加了請(qǐng)求攔截器和響應(yīng)攔截器。
在封裝接口的文件interface.js中,新增一個(gè)下載文件,并且獲取下載進(jìn)度的方法。
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.通過(guò)vuex狀態(tài)管理下載進(jìn)度
下載進(jìn)度對(duì)象,需要通過(guò)vuex狀態(tài)管理。在store文件下面的modules文件夾中,新建 downLoadProgress.js文件。
用來(lái)存放文件下載進(jìn)度的數(shù)組 progressList 和修改進(jìn)度列表方法,都在這里面。
const state = {
// 文件下載進(jìn)度
progressList: [],
progressError: '',
}
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{
// 當(dāng)前進(jìn)度列表為空,沒(méi)有下載任務(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
}
}
}
const actions = {
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}3.新增一個(gè)顯示進(jìn)度彈框的組件
<template>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'downLoadNotice',
computed: {
...mapState({
'progressList': state => state.downLoadProgress.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
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('downLoadProgress/DEL_PROGRESS', item.path)
this.$notify.error({
title: '錯(cuò)誤',
message: '文件下載失??!'
});
}
} else {
// 如果頁(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,
customClass: 'progress-notify',
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('downLoadProgress/DEL_PROGRESS', item.path)// 刪除caseInformation中state的progressList中的進(jìn)度對(duì)象
}
})
},
deep: true
}
}
}
</script>
<style lang="scss" scoped>
</style>到此這篇關(guān)于Vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能的文章就介紹到這了,更多相關(guān)Vue文件下載進(jìn)度條內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue2使用element-ui,el-table不顯示,用npm安裝方式
這篇文章主要介紹了vue2使用element-ui,el-table不顯示,用npm安裝方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Vue項(xiàng)目使用Websocket大文件FileReader()切片上傳實(shí)例
這篇文章主要介紹了Vue項(xiàng)目使用Websocket大文件FileReader()切片上傳實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
vue3 setup訪(fǎng)問(wèn)子組件的 DOM 元素的示例代碼
使用setup的情況下這個(gè)時(shí)候我們無(wú)法使用this,注意在setup中setup是封閉的,不會(huì)將子組件事件暴露出來(lái),所以要用defineExpose(),這篇文章主要介紹了vue3 setup訪(fǎng)問(wèn)子組件的 DOM 元素,需要的朋友可以參考下2023-08-08
詳解基于iview-ui的導(dǎo)航欄路徑(面包屑)配置
這篇文章主要介紹了詳解基于iview-ui的導(dǎo)航欄路徑(面包屑)配置,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
vue項(xiàng)目實(shí)現(xiàn)分頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了vue項(xiàng)目實(shí)現(xiàn)分頁(yè)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
vue2.x,vue3.x使用provide/inject注入的區(qū)別說(shuō)明
這篇文章主要介紹了vue2.x,vue3.x使用provide/inject注入的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
Vue之解決Echarts組件使用ID不能復(fù)用的問(wèn)題
這篇文章主要介紹了Vue之解決Echarts組件使用ID不能復(fù)用的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
仿照Element-ui實(shí)現(xiàn)一個(gè)簡(jiǎn)易的$message方法
這篇文章主要介紹了仿照Element-ui實(shí)現(xiàn)一個(gè)簡(jiǎn)易的$message方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
淺析Vue3中通過(guò)v-model實(shí)現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡(jiǎn)化父子組件雙向綁定
這篇文章主要介紹了淺析Vue3中通過(guò)v-model實(shí)現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡(jiǎn)化父子組件雙向綁定,需要的朋友可以參考下2022-12-12

