????????在 Vue 3 中,除了使用自定義的 useRequest
鉤子函數外,還可以通過 axios 的攔截器?或 axios-retry 插件實現接口請求失敗后的重試邏輯。以下是兩種具體方案的實現方式:
方案一:使用 axios 攔截器實現重試
???????實現步驟:?通過 axios 的響應攔截器捕獲錯誤,并在攔截器內部實現重試邏輯。
? ? ? ? 1、配置 axios 實例:在 Vue 項目的入口文件(如?main.js
)中配置 axios。
? ? ? ? 2、添加響應攔截器:在攔截器中捕獲錯誤,并根據條件進行重試。
? ? ? ? 3、遞歸重試:在攔截器中控制重試次數和延遲。
// main.js 或單獨的 axios 配置文件
import axios from 'axios';// 配置 axios 實例
const axiosInstance = axios.create({baseURL: '/api', // 根路徑timeout: 10000, // 超時時間
});// 響應攔截器:處理錯誤并重試
axiosInstance.interceptors.response.use((response) => response, // 成功響應直接返回async (error) => {const config = error.config;const status = error.response?.status;const maxRetries = 5; // 最大重試次數const retryDelay = 1000; // 重試間隔(毫秒)// 如果沒有重試次數或達到最大次數,直接拋出錯誤if (!config || !config._retryCount) {config._retryCount = 0;}if (config._retryCount >= maxRetries) {return Promise.reject(error);}// 增加重試次數config._retryCount += 1;// 只對特定狀態碼(如 408、5xx)重試if ([408, 500, 502, 503, 504].includes(status) ||(status === 401 && config.url.includes('/refresh-token')) // 示例:401 時重試刷新 token) {// 等待一段時間后重試await new Promise((resolve) => setTimeout(resolve, retryDelay * config._retryCount));// 重新發送請求return axiosInstance(config);}// 其他錯誤直接拋出return Promise.reject(error);}
);// 導出配置好的 axios 實例
export default axiosInstance;
使用示例(在 Vue 組件中)
<template><div><button @click="fetchData">獲取數據</button><div v-if="loading">加載中...</div><div v-else-if="data">數據:{{ data }}</div><div v-else-if="error">錯誤:{{ error.message }}</div></div>
</template><script setup>
import axiosInstance from '@/utils/axios'; // 導入配置好的 axios 實例
import { ref } from 'vue';const loading = ref(false);
const data = ref(null);
const error = ref(null);const fetchData = async () => {try {loading.value = true;const response = await axiosInstance.get('/data');data.value = response.data;error.value = null;} catch (err) {error.value = err;} finally {loading.value = false;}
};
</script>
? ? ? ? 1、攔截器全局生效:所有通過?axiosInstance
?發起的請求都會經過攔截器,自動處理重試邏輯。可通過配置?config
?參數(如?config._retryCount
)控制重試次數。
? ? ? ? 2、重試條件:根據 HTTP 狀態碼(如 408、5xx)決定是否重試。可擴展為根據業務邏輯(如 token 過期后刷新)觸發重試。
? ? ? ? 3、遞歸重試:通過?axiosInstance(config)
?重新發送請求,遞歸調用攔截器。需要手動維護?config._retryCount
?來計數。
方案二:使用 axios-retry 插件
????????通過 axios-retry
插件快速實現重試邏輯,無需手動編寫遞歸邏輯。
????????1、安裝插件:
npm install axios-retry
????????2、配置 axios 實例:
// main.js 或單獨的 axios 配置文件
import axios from 'axios';
import axiosRetry from 'axios-retry';const axiosInstance = axios.create({baseURL: '/api',timeout: 10000,
});// 配置重試策略
axiosRetry(axiosInstance, {retries: 5, // 最大重試次數retryDelay: (retryCount) => {return retryCount * 1000; // 指數退避:1s、2s、3s...},retryCondition: (error) => {// 自定義重試條件(如針對特定狀態碼)if (error.response) {return [408, 500, 502, 503, 504].includes(error.response.status);}return axiosRetry.isNetworkError(error); // 網絡錯誤自動重試},
});export default axiosInstance;
????????3、使用示例(與方案一相同)
<template><!-- 同上 -->
</template><script setup>
import axiosInstance from '@/utils/axios'; // 已配置重試的 axios 實例
// 同上
</script>
關鍵點說明
? ? ? ? 1、插件優勢:開箱即用,代碼簡潔。支持自定義重試條件、延遲策略(如指數退避)。
內置對網絡錯誤(如超時)的自動重試。
? ? ? ? 2、靈活性:可通過?retryCondition
?函數靈活控制重試條件。支持?retryDelay
?函數實現動態延遲(如指數退避)。
對比與選擇
方案 | 優點 | 缺點 |
---|---|---|
攔截器手動實現 | 完全自定義邏輯,無依賴 | 代碼冗余,需手動維護計數器 |
axios-retry 插件 | 簡單易用,開箱即用 | 需引入第三方依賴 |
注意事項
????????1、避免無限循環:必須設置最大重試次數(如?maxRetries
?或?retries
?參數)。確保重試條件不會無限觸發(如?401 未授權
?需結合 token 刷新邏輯)。
????????2、錯誤類型區分:對于?4xx 客戶端錯誤(如 400、401、403),通常不建議重試,需業務邏輯處理(如跳轉登錄頁)。對?5xx 服務端錯誤(如 500、503)或網絡錯誤(如超時),可安全重試。
????????3、性能優化:使用?指數退避(如?retryDelay: (count) => Math.pow(2, count) * 1000
)減少并發重試的壓力。結合?限流(如?maxRetries
?與?retryDelay
?組合)避免頻繁請求。