從eleUI的Loading知道了單例模式的用法
從eleUI的Loading知道了單例模式
現(xiàn)象
在使用elementUI
開始一個vue項目,
為了更好的用戶體驗,需要在接口請求的時候添加全局的Loading
所以在接口處理文件中,
在請求攔截的時候添加Loading
,在響應(yīng)攔截的時候取消Loading
:
import axios from 'axios' import { Message, Loading } from 'element-ui' let instance = axios.create({ baseURL: '', timeout: 60000 }) let loadingInstance = null // 請求攔截 instance.interceptors.request.use((config) => { loadingInstance = Loading.service({ fullscreen: true, text: '拼命加載中...', background: 'rgba(0, 0, 0, 0.8)' }) return config }, (error) => { loadingInstance.close() Message.error({message: '請求超時!'}) return Promise.reject(error) }) // 響應(yīng)攔截 instance.interceptors.response.use((response) => { loadingInstance.close() if (response.data && response.data.code && response.data.code === 200) { return response.data } else { Message({ message: response.data.msg || '接口錯誤', type: 'error' }) } }, (error) => { loadingInstance.close() return Promise.reject(error) }) export default instance
優(yōu)化
邏輯似乎很合理,但是實際項目中發(fā)現(xiàn),如果某個頁面請求多個接口,且每個接口都返回很慢的話,實際看到的效果是雖然Loading
會出現(xiàn),但是當(dāng)?shù)谝粋€接口返回值以后后面的Loading
都不會出現(xiàn)了,就會出現(xiàn)頁面數(shù)據(jù)從無到有的過濾,用戶體驗較差。
原來,是因為elementUI
的全屏Loading
是單例的:如果前一個Loading
關(guān)閉之前再次調(diào)用了下一個Loading
并不會創(chuàng)建一個新的實例,返回的仍然是當(dāng)前這個Loading
實例;同理,當(dāng)調(diào)用任意一個close()
方法都會關(guān)閉這個Loading
實例。
因為這幾個接口都是同一時間請求的,也就是說當(dāng)前頁面幾個Loading
實例其實都是同一個,所以關(guān)閉后也就都關(guān)閉了。
改進(jìn)后:
import axios from 'axios' import { Message, Loading } from 'element-ui' let instance = axios.create({ baseURL: '', timeout: 60000 }) /* 當(dāng)頁面有兩個接口時,第一個接口loading的close事件會直接將第二個接口的loading實例也close */ let loadingInstance = null function startLoading () { loadingInstance = Loading.service({ fullscreen: true, text: '拼命加載中...', background: 'rgba(0, 0, 0, 0.8)' }) } function endLoading () { loadingInstance.close() } let needLoadingRequestCount = 0 function showFullScreenLoading () { if (needLoadingRequestCount === 0) { startLoading() } needLoadingRequestCount++ } function tryHideFullScreenLoading () { if (needLoadingRequestCount <= 0) return needLoadingRequestCount-- if (needLoadingRequestCount === 0) { endLoading() } } // 請求攔截 instance.interceptors.request.use((config) => { showFullScreenLoading() return config }, (error) => { tryHideFullScreenLoading() Message.error({message: '請求超時!'}) return Promise.reject(error) }) // 響應(yīng)攔截 instance.interceptors.response.use((response) => { tryHideFullScreenLoading() if (response.data && response.data.code && response.data.code === 200) { return response.data } else { Message({ message: response.data.msg || '接口錯誤', type: 'error' }) } }, (error) => { tryHideFullScreenLoading() return Promise.reject(error) }) export default instance
每次創(chuàng)建Loading
實例的時候判斷當(dāng)前是否存在,如果當(dāng)前還沒有Loading
實例就創(chuàng)建一個,如果有就不會再創(chuàng)建而是計數(shù);
每次關(guān)閉的時候判斷當(dāng)前的計數(shù),如果是0了就關(guān)閉,否則也計數(shù)減一,直到為0的時候表示當(dāng)前所有頁面所有接口都返回結(jié)束了,此時執(zhí)行關(guān)閉Loading.close()
操作關(guān)閉菊花。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue?watch中監(jiān)聽值的變化,判斷后修改值方式
這篇文章主要介紹了Vue?watch中監(jiān)聽值的變化,判斷后修改值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04Vuex2.0+Vue2.0構(gòu)建備忘錄應(yīng)用實踐
這篇文章主要為大家詳細(xì)介紹了Vuex2.0+Vue2.0構(gòu)建備忘錄應(yīng)用實踐,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11Element-UI結(jié)合遞歸組件實現(xiàn)后臺管理系統(tǒng)左側(cè)菜單
在Vue.js中使用遞歸組件可以方便地構(gòu)建多層級的菜單結(jié)構(gòu),遞歸組件適用于處理具有嵌套關(guān)系的數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09vue2項目導(dǎo)出操作實現(xiàn)方法(后端接口導(dǎo)出、前端直接做導(dǎo)出)
這篇文章主要給大家介紹了關(guān)于vue2項目導(dǎo)出操作實現(xiàn)方法的相關(guān)資料,文中介紹的是后端接口導(dǎo)出、前端直接做導(dǎo)出,通過代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-05-05vue中el-select 和el-tree二次封裝實現(xiàn)
本文介紹了vue中el-select 和el-tree二次封裝實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11