Vue項目實現(xiàn)文件下載進度條功能
Vue項目實現(xiàn)文件下載進度條
需求場景
大文件下載,花費的時間比較長,沒有任何提示,用戶體驗很差。
需要優(yōu)化,提示文件在下載中,并且顯示進度百分比。
實現(xiàn)步驟
1.下載文件的方法,需要拿到當(dāng)前進度。
2.每一次下載進度更新,需要監(jiān)聽變化,并且刷新頁面顯示的數(shù)據(jù)。
3.封裝一個文件下載進度的組件。
下面一步步來實現(xiàn):
1.獲取文件下載進度
axios作為一個易用、簡潔且高效的http庫,有沒有獲取下載進度的方法呢?
打開axios官網(wǎng)查看一下,文檔中有一個對原生進度事件的處理的方法
onDownloadProgress
允許為下載處理進度事件。
在項目中,我已經(jīng)對axios進行了封裝,并且增加了請求攔截器和響應(yīng)攔截器。
在封裝接口的文件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狀態(tài)管理下載進度
下載進度對象,需要通過vuex狀態(tài)管理。在store文件下面的modules文件夾中,新建 downLoadProgress.js文件。
用來存放文件下載進度的數(shù)組 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時間戳是唯一存在的,所以如果在進度列表中找到當(dāng)前的進度對象
state.progressList.find(item=>item.path == progressObj.path).progress = progressObj.progress
// 改變當(dāng)前進度對象的progress
}
}else{
// 當(dāng)前進度列表為空,沒有下載任務(wù),直接將該進度對象添加到進度數(shù)組內(nèi)
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: {} // 用來維護下載文件進度彈框?qū)ο?
}
},
watch: { // 監(jiā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)) { // 如果頁面已經(jīng)有該進度對象的彈框,則更新它的進度progress
if(item.progress)domList.find(i => i.className == item.path).innerHTML = item.progress + '%'
if (item.progress === null) { // 此處容錯處理,如果后端傳輸文件流報錯,刪除當(dāng)前進度對象
this.$store.commit('downLoadProgress/DEL_PROGRESS', item.path)
this.$notify.error({
title: '錯誤',
message: '文件下載失敗!'
});
}
} else {
// 如果頁面中沒有該進度對象所對應(yīng)的彈框,頁面新建彈框,并在notify中加入該彈框?qū)ο?,屬性名為該進度對象的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>`, // 顯示下載百分比,類名為進度對象的path(便于后面更新進度百分比)
showClose: false,
duration: 0
})
}
console.log(item.progress + '%', '-------------------------->')
if (item.progress == 100) { // 如果下載進度到了100%,關(guān)閉該彈框,并刪除notify中維護的彈框?qū)ο?
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>到此這篇關(guān)于Vue項目實現(xiàn)文件下載進度條功能的文章就介紹到這了,更多相關(guān)Vue文件下載進度條內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue2使用element-ui,el-table不顯示,用npm安裝方式
這篇文章主要介紹了vue2使用element-ui,el-table不顯示,用npm安裝方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
Vue項目使用Websocket大文件FileReader()切片上傳實例
這篇文章主要介紹了Vue項目使用Websocket大文件FileReader()切片上傳實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
詳解基于iview-ui的導(dǎo)航欄路徑(面包屑)配置
這篇文章主要介紹了詳解基于iview-ui的導(dǎo)航欄路徑(面包屑)配置,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02
vue2.x,vue3.x使用provide/inject注入的區(qū)別說明
這篇文章主要介紹了vue2.x,vue3.x使用provide/inject注入的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
Vue之解決Echarts組件使用ID不能復(fù)用的問題
這篇文章主要介紹了Vue之解決Echarts組件使用ID不能復(fù)用的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
仿照Element-ui實現(xiàn)一個簡易的$message方法
這篇文章主要介紹了仿照Element-ui實現(xiàn)一個簡易的$message方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
淺析Vue3中通過v-model實現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡化父子組件雙向綁定
這篇文章主要介紹了淺析Vue3中通過v-model實現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡化父子組件雙向綁定,需要的朋友可以參考下2022-12-12

