通常狀況下,在 vue 中結合 axios 的攔截器控制 loading 展現和關閉,是這樣的:
在 App.vue
配置一個全局 loading。html
<div class="app"> <keep-alive :include="keepAliveData"> <router-view/> </keep-alive> <div class="loading" v-show="isShowLoading"> <Spin size="large"></Spin> </div> </div>
同時設置 axios 攔截器。vue
// 添加請求攔截器 this.$axios.interceptors.request.use(config => { this.isShowLoading = true return config }, error => { this.isShowLoading = false return Promise.reject(error) }) // 添加響應攔截器 this.$axios.interceptors.response.use(response => { this.isShowLoading = false return response }, error => { this.isShowLoading = false return Promise.reject(error) })
這個攔截器的功能是在請求前打開 loading,請求結束或出錯時關閉 loading。
若是每次只有一個請求,這樣運行是沒問題的。但同時有多個請求併發,就會有問題了。ios
舉例:git
假如如今同時發起兩個請求,在請求前,攔截器 this.isShowLoading = true
將 loading 打開。
如今有一個請求結束了。this.isShowLoading = false
攔截器關閉 loading,可是另外一個請求因爲某些緣由並無結束。
形成的後果就是頁面請求還沒完成,loading 卻關閉了,用戶會覺得頁面加載完成了,結果頁面不能正常運行,致使用戶體驗很差。github
解決方案
增長一個 loadingCount
變量,用來計算請求的次數。axios
loadingCount: 0
再增長兩個方法,來對 loadingCount
進行增減操做。網絡
methods: { addLoading() { this.isShowLoading = true this.loadingCount++ }, isCloseLoading() { this.loadingCount-- if (this.loadingCount == 0) { this.isShowLoading = false } } }
如今攔截器變成這樣:併發
// 添加請求攔截器 this.$axios.interceptors.request.use(config => { this.addLoading() return config }, error => { this.isShowLoading = false this.loadingCount = 0 this.$Message.error('網絡異常,請稍後再試') return Promise.reject(error) }) // 添加響應攔截器 this.$axios.interceptors.response.use(response => { this.isCloseLoading() return response }, error => { this.isShowLoading = false this.loadingCount = 0 this.$Message.error('網絡異常,請稍後再試') return Promise.reject(error) })
這個攔截器的功能是:
每當發起一個請求,打開 loading,同時 loadingCount
加1。
每當一個請求結束, loadingCount
減1,並判斷 loadingCount
是否爲 0,若是爲 0,則關閉 loading。
這樣便可解決,多個請求下有某個請求提早結束,致使 loading 關閉的問題。app