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