一文教你如何優雅的控制全域性loading的顯示
在很多後臺管理系統中,傳送請求的時候,需要開啟一個loading,收到響應後,需要關閉這個loading,對於這種通用的邏輯,我一般是在axios攔截器中做這種處理,因為不是每個請求都需要全域性顯示loading,所以我在axios config中添加了一個標記showLoading,用於標記傳送請求之前是否需要顯示loading,自然收到響應後,根據這個標記確定是否需要關閉loading,在axios攔截器中的程式碼如下:
axios.interceptors.request.use( (config) => { // config中不設定showLoading這個欄位或者這個欄位為true時,代表需要全域性顯示loading if (config.headers.showLoading !== false) { // 全域性顯示loading Loading.showLoading(); } return config; },(err) => { return Promise.reject(err); },); instance.interceptors.response.use( (response) => { const { config: { headers } } = response; if (headers.showLoading !== false) { // 關閉全域性的loading Loading.hideLoading(); } return data; } );
我自己自然覺得上面那個實現自然滿足要求了,但是偶然一次和後端同事聊起這個問題,後端同事說,這個前端的標記(showLoading)怎麼能傳遞給後端伺服器了,並且還說,如果是他和我對接,絕對不允許我這麼做。然後我就懵逼了,因為想不到解決辦法。
直到後來瞭解到洋蔥模型,其實請求,響應天然的適用洋蔥模型,如果給axios新增上洋蔥模型,這個問題就自然而然解決了啊。下面講解如何給axios新增洋蔥模型,如果有了洋蔥模型,axios攔截器就沒有必要了,因為洋蔥模型比axios攔截器更好用。
- 宣告MiddleWareManager類,這個類是洋蔥模型的具體實現,程式碼如下。
// 中介軟體管理器,用於新增,刪除中介軟體。 // 另外這個新增的中介軟體給誰用,也需要用引數(job)儲存起來。 class MiddleWarwww.cppcns.comeManager { // 新增的中介軟體是給誰用的,我們用job標識,如果中介軟體是給axios用,那麼這個job就是axios方法。 // middleWares用來儲存中介軟體。 // job和中介軟體都是返回Promise物件的方法。 // 其中,job接受一個引數config,由最後一箇中間件傳遞。 // 中介軟體接受兩個引數,一個是他之前的中介軟體傳遞的config,一個是執行下一個中介軟體的方法。 constructor(job) { // 這裡預設加上axios請求 this.job = job; this.middleWacDaMQVGcZres = []; } use(middleWare) { this.middleWares.unshift(middleWare); return this; } remove(middleWare) { const index = this.middleWares.indexOf(middleWare); this.middleWares.splice(index,1); return this; } run(config) { const { length } = this.middleWares; function innerRun(config,index) { // 如果中介軟體已經執行完畢,這直接job函式。 if (index >= length) { return this.job(config); } // 否則執行下一個中介軟體函式 return this.middleWares[index](config,(config) => innerRun(config,index++)); } innerRun(config,0); } }
- MiddleWareManager已經實現,接下來是講解如何將MiddleWareManager和axios組合到一起使用。我們會定義一個request方法,當我們需要傳送請求的時候,我們就統一呼叫request方法。
// middleWare1用於處理是否需要全域性的顯示loading
async function middleWare1(config,next) {
// 檢視config中是否有showLoading標記,如果沒有或者為true, 則需要全域性顯示loading,// 當接收到響應後,自然需要關閉loading
// 自然收到響應後,根據這個標記確定是否需要關閉loading
const { showLoading,...rest } = conwww.cppcns.comfig;
if (showLoading !== false) {
// 顯示loading動畫
}
const response = await next(rest);
if (showLoading !== false) {
// 關閉動畫
}
return response;
}
// 組裝MiddleWareManager
const manager = new MiddleWareManager(axioscDaMQVGcZ);
manager.use(middleWare1);
// 實現request方法,用於傳送請求
function request(config) {
return manager.run(config);
}
- 當我們傳送請求需要全域性開啟loading時,像如下做
request({ url: 'xxx',method: 'get' })
這樣在傳送請求前,會自動開啟loading,當接收到響應後,會自動關閉loading. 當我們不需要自動開啟loading的功能時,我們只需要在傳送請求時在config中新增showLoading: false就可以了,程式碼如下
request({ url: 'xxx',method: 'get',showLoading: false })
這樣做是不是滿足了後端同事的要求了呢!並且洋蔥模型也比攔截器使用起來更加方便,特別是在請求和響應中訪問相同的變數的時候。就如我們例子中的showLoading. 當然我們也可以把攔截器中的更多功能移到洋蔥模型的中介軟體中,比如傳送請求時,自動新增token。
總結
到此這篇關於如何優雅的控制全域性loading的顯示的文章就介紹到這了,更多相關控制全域性loading顯示內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!