vue使用axios的小技巧分享
全局loading
在日常開發(fā)工作中,每次使用api
請求數(shù)據(jù)時,都會涉及添加loading
狀態(tài),從而達(dá)到優(yōu)化用戶體驗的效果,特別是對于請求時間較長的接口時。這樣每次請求開始時就要添加loading
狀態(tài),請求完成時要移除loading
狀態(tài),導(dǎo)致重復(fù)又繁瑣的工作。所以我們可以思考從axios方向著手,嘻嘻嘻...
思路
創(chuàng)建axios函數(shù) 我們采用axios.create()
創(chuàng)建http
方法
/** * Axios實例化參數(shù)選項對象 * @const * @type {object} * @property {object} headers 請求頭對象對象,默認(rèn):null * @property {number} timeout 超時時間,默認(rèn):0, 不限制 * @property {boolean} withCredentials 是否帶上驗證信息, 默認(rèn):true * @property {number} maxContentLength 限制最大發(fā)送內(nèi)容長度,默認(rèn):-1 不限制 * @property {strin} baseURL 默認(rèn)請求拼接的前綴 */ const http = axios.create({ headers: { 'Content-Type': 'application/json;charset=UTF-8', // ie瀏覽器get請求兼容問題 'Cache-Control': 'no-cache', 'If-Modified-Since': '0' }, timeout: 0, withCredentials: false, responseType: 'json', maxContentLength: -1, baseURL: import.meta.env.VITE_APP_BASE_API }); export default http
添加loading
axios具有請求攔截器以及響應(yīng)攔截器的特性進(jìn)行處理。我們在請求攔截器觸發(fā)時添加loading
,響應(yīng)攔截器觸發(fā)時移除loading
。
import { ElLoading } from 'element-plus'; // 全局loading let loadingInstance; /** * Axios實例化參數(shù)選項對象 * @const * @type {object} * @property {object} headers 請求頭對象對象,默認(rèn):null * @property {number} timeout 超時時間,默認(rèn):0, 不限制 * @property {boolean} withCredentials 是否帶上驗證信息, 默認(rèn):true * @property {number} maxContentLength 限制最大發(fā)送內(nèi)容長度,默認(rèn):-1 不限制 * @property {strin} baseURL 默認(rèn)請求拼接的前綴 */ const http = axios.create({ headers: { 'Content-Type': 'application/json;charset=UTF-8', // ie瀏覽器get請求兼容問題 'Cache-Control': 'no-cache', 'If-Modified-Since': '0' }, timeout: 0, withCredentials: false, responseType: 'json', maxContentLength: -1, baseURL: import.meta.env.VITE_APP_BASE_API }); /** * 請求攔截器 */ http.interceptors.request.use((config) => { // 創(chuàng)建全局loading loadingInstance = ElLoading.service({ text: '加載中...', target: '#ContentArea' }); return config; }); // 響應(yīng)攔截器 http.interceptors.response.use((res) => { nextTick(() => { loadingInstance?.close(); }); }); export default http
注意
這個時候乍一看是沒有什么問題的,但是當(dāng)多個請求同時執(zhí)行時,每個請求都會添加全局loading
,當(dāng)?shù)谝粋€請求完成時全局loading
就被移除了,實際上應(yīng)該是最后一個請求完成時,才移除全局loading
。
處理loading
混亂 基于loading
的攔截器,我們可以定義一個請求隊列,對當(dāng)前正在進(jìn)行中的請求進(jìn)行管理,在請求攔截器中將該請求添加進(jìn)請求隊列中,當(dāng)請求隊列的長度為0時,添加loading
,在響應(yīng)攔截器中將該請求從請求隊列中移除,當(dāng)請求隊列的長度為0時,移除loading
。
import { ElLoading } from 'element-plus'; // 請求隊列 const httpPromiseArr = new Map(); // 全局loading let loadingInstance; /** * 判斷是否為JSON格式 * @param {*} str * @returns */ function isJSON(str) { if (typeof str == 'string') { try { JSON.parse(str); return true; } catch (e) { return false; } } } /** * 創(chuàng)建緩存key, 由請求url、類型、參數(shù)、發(fā)送數(shù)據(jù)構(gòu)成的標(biāo)識符 * @param {string} url 請求url * @param {string} type 請求類型 * @param {object} params url參數(shù)對象 * @param {object} data 請求數(shù)據(jù) * @return {string} */ function createKey(config) { const { url, method, params = {}, data = {} } = config; return encodeURIComponent( [url, method, isJSON(params) ? params : JSON.stringify(params), isJSON(data) ? data : JSON.stringify(data)].join( ',' ) ); } /** * Axios實例化參數(shù)選項對象 * @const * @type {object} * @property {object} headers 請求頭對象對象,默認(rèn):null * @property {number} timeout 超時時間,默認(rèn):0, 不限制 * @property {boolean} withCredentials 是否帶上驗證信息, 默認(rèn):true * @property {number} maxContentLength 限制最大發(fā)送內(nèi)容長度,默認(rèn):-1 不限制 * @property {strin} baseURL 默認(rèn)請求拼接的前綴 */ const http = axios.create({ headers: { 'Content-Type': 'application/json;charset=UTF-8', // ie瀏覽器get請求兼容問題 'Cache-Control': 'no-cache', 'If-Modified-Since': '0' }, timeout: 0, withCredentials: false, responseType: 'json', maxContentLength: -1, baseURL: import.meta.env.VITE_APP_BASE_API }); /** * 請求攔截器 */ http.interceptors.request.use((config) => { if (httpPromiseArr.size === 0) { // 創(chuàng)建全局loading loadingInstance = ElLoading.service({ text: '加載中...' }); } httpPromiseArr.set(createKey(config)); return config; }); // 響應(yīng)攔截器 http.interceptors.response.use((res) => { const key = createKey(res.config); if (httpPromiseArr.has(key)) { httpPromiseArr.delete(key); } // 全部請求結(jié)束關(guān)閉loading if (httpPromiseArr.size === 0) { nextTick(() => { loadingInstance?.close(); }); } }); export default http
總結(jié)
思路就是使用隊列來管理請求的方式來實現(xiàn),基于此思路同樣可以完成,在同一時間內(nèi)禁止同意請求的多次觸發(fā),也就是攔截同一請求,進(jìn)行性能優(yōu)化。
到此這篇關(guān)于vue使用axios的小技巧分享的文章就介紹到這了,更多相關(guān)vue使用axios內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Webpack提高Vue.js應(yīng)用的方式匯總(四種)
Webpack是開發(fā)Vue.js單頁應(yīng)用程序的重要工具。下面通過四種方式給大家介紹使用Webpack提高Vue.js應(yīng)用,需要的的朋友參考下吧2017-07-07vue中json格式化顯示數(shù)據(jù)(vue-json-viewer)
這篇文章主要給大家介紹了關(guān)于vue中json格式化顯示數(shù)據(jù)(vue-json-viewer)的相關(guān)資料,Vue-json-viewer是一個Vue組件,用于在Vue應(yīng)用中顯示JSON數(shù)據(jù)的可視化工具,需要的朋友可以參考下2024-05-05解決Vuepress碼云部署及自動跳轉(zhuǎn)404的問題
這篇文章主要介紹了解決Vuepress碼云部署及自動跳轉(zhuǎn)404的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09vue3中g(shù)etCurrentInstance示例講解
這篇文章主要給大家介紹了關(guān)于vue3中g(shù)etCurrentInstance的相關(guān)資料,文中還介紹了Vue3中關(guān)于getCurrentInstance的大坑,需要的朋友可以參考下2023-03-03vue路由$router.push()使用query傳參的實際開發(fā)使用
在vue項目中我們用函數(shù)式編程this.$router.push跳轉(zhuǎn),用query傳遞一個對象時要把這個對象先轉(zhuǎn)化為字符串,然后在接收的時候要轉(zhuǎn)化為對象,下面這篇文章主要給大家介紹了關(guān)于vue路由$router.push()使用query傳參的實際開發(fā)使用,需要的朋友可以參考下2022-11-11