elementUI全局loading單例模式


前面寫過一次loading組件的js組件使用:

### 封裝Loading組件-JS組

 

elementUI提供了loading組件的簡便使用:

1、在table等組件上綁定指令:v-loading="loading",然后通過控制變量loading的值為true或false,切換顯示和隱藏

<el-table v-loading="loading">

2、在使用指令的基礎上,自定義加載文案、圖標和背景色:

<el-table
    v-loading="loading"
    element-loading-text="拼命加載中"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(0, 0, 0, 0.8)"
    :data="tableData">

3、以上都是給單個的組件添加loading條,如果要給整頁進行加載:fullscreen修飾符將遮罩插入到body上,lock修飾符鎖定屏幕滾動

<el-button v-loading.fullscreen.lock="fullscreenLoading">指令方式</el-button>

4、整頁加載可以使用服務的方式,遮罩默認為全屏,不需要額外設置修飾符fullscreen:

<el-button @click="handleClick">服務方式</el-button>
      handleClick() {
        const loading = this.$loading({
          lock: true,
          text: 'Loading',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });
        setTimeout(() => {
          loading.close();
        }, 2000);
      }

5、配合axios做全局的設置:

實際項目中發現,如果某個頁面請求多個接口,且每個接口都返回很慢的話,實際看到的效果是雖然Loading會出現,但是當第一個接口返回值以后后面的Loading都不會出現了,就會出現頁面數據從無到有的過濾,用戶體驗較差。

原來,是因為elementUI的全屏Loading是單例的:如果前一個Loading關閉之前再次調用了下一個Loading並不會創建一個新的實例,返回的仍然是當前這個Loading實例;同理,當調用任意一個close()方法都會關閉這個Loading實例。因為這幾個接口都是同一時間請求的,也就是說當前頁面幾個Loading實例其實都是同一個,所以關閉后也就都關閉了。

import axios from 'axios'
import { Message, Loading } from 'element-ui'
let instance = axios.create({
  baseURL: '',
  timeout: 60000
})
/* 當頁面有兩個接口時,第一個接口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)
})
// 響應攔截
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

每次創建Loading實例的時候判斷當前是否存在,如果當前還沒有Loading實例就創建一個,如果有就不會再創建而是計數;每次關閉的時候判斷當前的計數,如果是0了就關閉,否則也計數減一,直到為0的時候表示當前所有頁面所有接口都返回結束了,此時執行關閉Loading.close()操作關閉菊花。

service()中沒有參數對象時,

有參數對象時,

  loadingInstance = Loading.service({
    fullscreen: true,
    text: '拼命加載中...',
    background: 'rgba(0, 0, 0, 0.8)'
  })

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM