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)有任何提示,用戶體驗(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)度的方法呢?
打開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>`, // 顯示下載百分比,類名為進(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-07Vue項(xiàng)目使用Websocket大文件FileReader()切片上傳實(shí)例
這篇文章主要介紹了Vue項(xiàng)目使用Websocket大文件FileReader()切片上傳實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10vue3 setup訪問(wèn)子組件的 DOM 元素的示例代碼
使用setup的情況下這個(gè)時(shí)候我們無(wú)法使用this,注意在setup中setup是封閉的,不會(huì)將子組件事件暴露出來(lái),所以要用defineExpose(),這篇文章主要介紹了vue3 setup訪問(wèn)子組件的 DOM 元素,需要的朋友可以參考下2023-08-08詳解基于iview-ui的導(dǎo)航欄路徑(面包屑)配置
這篇文章主要介紹了詳解基于iview-ui的導(dǎo)航欄路徑(面包屑)配置,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02vue項(xiàng)目實(shí)現(xiàn)分頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了vue項(xiàng)目實(shí)現(xiàn)分頁(yè)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03vue2.x,vue3.x使用provide/inject注入的區(qū)別說(shuō)明
這篇文章主要介紹了vue2.x,vue3.x使用provide/inject注入的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Vue之解決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