2025了,Vue3 中做輪詢的幾種最新方式
在 Vue3 中實(shí)現(xiàn)輪詢請(qǐng)求,以下是幾個(gè)值得推薦的解決方案和庫(kù)(包含原生方案和第三方庫(kù)),我根據(jù)實(shí)際開發(fā)經(jīng)驗(yàn)為你整理推薦清單:
方案 | 特點(diǎn) | 適用場(chǎng)景 | 包大小 | 文檔評(píng)級(jí) |
vue-request | 功能全面的請(qǐng)求庫(kù),內(nèi)置輪詢 | 需要完整請(qǐng)求管理 | 5.2kb | ???? |
axios + 自封裝 | 靈活可控,需自行處理 | 簡(jiǎn)單輪詢需求 | 0kb | ?? |
rxjs | 響應(yīng)式編程庫(kù) | 復(fù)雜輪詢邏輯 | 32kb | ??? |
@vueuse/core | 組合式API工具庫(kù) | 組合式API項(xiàng)目 | 12kb | ???? |
具體實(shí)現(xiàn)方案
(1) 推薦首選:vue-request(專為Vue3設(shè)計(jì))
npm install vue-request
<script setup>
import { useRequest } from 'vue-request';
// 輪詢獲取數(shù)據(jù)示例
const { data, loading } = useRequest(
() => axios.get('/api/data'),
{
// 每3秒輪詢一次
pollingInterval: 3000,
// 錯(cuò)誤重試策略
pollingWhenHidden: false, // 頁面隱藏時(shí)暫停
pollingErrorRetryCount: 3
}
);
</script>
<template>
<div v-if="loading">加載中...</div>
<div v-else>{{ data }}</div>
</template>
(2) 原生方案:使用 Composition API 封裝
// utils/usePolling.ts
import { ref, onUnmounted } from'vue';
exportfunction usePolling<T>(fn: () => Promise<T>, interval: number) {
const data = ref<T>();
const error = ref<Error>();
const isPolling = ref(true);
let timer: number;
const execute = async () => {
try {
data.value = await fn();
} catch (err) {
error.value = err asError;
} finally {
if (isPolling.value) {
timer = setTimeout(execute, interval);
}
}
};
const stop = () => {
isPolling.value = false;
clearTimeout(timer);
};
// 自動(dòng)開始
execute();
// 組件卸載時(shí)自動(dòng)清理
onUnmounted(stop);
return { data, error, stop };
}
<script setup>
import { usePolling } from './utils/usePolling';
const { data, stop } = usePolling(
() => fetch('/api/data').then(r => r.json()),
5000
);
</script>
(3) 輕量級(jí)方案:@vueuse/core(推薦組合式API項(xiàng)目)
npm install @vueuse/core
<script setup>
import { useIntervalFn } from '@vueuse/core';
const data = ref();
const error = ref();
// 每5秒執(zhí)行一次
const { pause, resume } = useIntervalFn(async () => {
try {
data.value = await axios.get('/api/data');
} catch (err) {
error.value = err;
pause(); // 出錯(cuò)時(shí)暫停
}
}, 5000, { immediate: true });
</script>
(4) RxJS 方案(適合復(fù)雜場(chǎng)景)
npm install rxjs
<script setup>
import { interval, switchMap } from 'rxjs';
import { useObservable } from '@vueuse/rxjs';
const poll$ = interval(3000).pipe(
switchMap(() => from(axios.get('/api/data')))
);
const data = useObservable(poll$);
</script>
選型建議
簡(jiǎn)單場(chǎng)景:
- 使用 @vueuse/core 的 useIntervalFn
- 優(yōu)點(diǎn):無需額外依賴,組合式API友好
- 注意:需自行處理錯(cuò)誤和清理
完整請(qǐng)求管理:
- 選擇 vue-request
- 優(yōu)點(diǎn):內(nèi)置錯(cuò)誤重試、緩存、節(jié)流等高級(jí)功能
復(fù)雜輪詢邏輯:
- 采用 RxJS
- 優(yōu)點(diǎn):處理競(jìng)態(tài)條件、重試策略等復(fù)雜場(chǎng)景得心應(yīng)手
需要精細(xì)控制:
- 自行封裝(推薦 usePolling 方案)
- 優(yōu)點(diǎn):完全可控,適合特殊業(yè)務(wù)需求