Skip to content

请求状态 Hooks:useRequest ​

useRequest 包裹任意 async 函数,集中维护 loading / error / data:代次计数丢弃过期响应(快速翻页不串数据)、失败自动重试(固定间隔)、run 防抖、refresh 按上次入参重跑、mutate 乐观更新。不绑定 HTTP 库——fetch / axios / 自定义服务皆可。

基本用法 ​

vue
<script setup lang="ts">
import { useRequest } from 'vue3-ep-biz-lib'

interface User { id: string; name: string }

const fetchUser = (id: string): Promise<User> =>
  fetch(`/api/users/${id}`).then((res) => res.json())

const { data, loading, error, run } = useRequest(fetchUser, {
  immediate: true,
  defaultParams: ['u1'],
  onSuccess: (user) => console.log(user.name),
})

// 手动重新执行
const reload = (): void => { void run('u2') }
</script>

<template>
  <el-skeleton :loading="loading" :rows="3">
    <div v-if="error">加载失败</div>
    <div v-else-if="data">{{ data.name }}</div>
  </el-skeleton>
</template>

重试与防抖 ​

ts
const { run: submit } = useRequest(saveOrder, {
  debounce: 300,          // 连点只发最后一次
  retry: 2,               // 失败自动重试 2 次
  retryDelay: 1000,       // 重试间隔
  onError: (err) => console.warn(err),
})

配合分页刷新 ​

ts
const pager = usePagination()
const search = useRequest(
  (page: number, size: number) => api.list({ page, size, keyword: keyword.value }),
  {
    onSuccess: (res) => pager.setTotal(res.total),
  },
)
// pager onChange → search.refresh()

API ​

useRequest(fetcher, options): UseRequestReturn<TData, TParams> ​

成员类型说明
dataShallowRef<TData | null>最近一次成功数据(未成功为 null)
loadingRef<boolean>请求中
errorRef<unknown>最近一次失败(重试耗尽后)
run(...params) => Promise<TData | null>手动执行(可防抖);返回成功数据或 null
refresh() => Promise<TData | null>以上次入参重跑
mutate(data: TData | null) => void本地改写 data(乐观更新)

options ​

属性类型默认值说明
immediatebooleanfalse挂载后立即执行(onMounted 时机,SSG 安全)
defaultParamsTParams[]立即执行 / refresh 入参
onSuccess(data, params) => void—成功回调
onError(error, params) => void—失败回调(重试耗尽后)
debouncenumber0run 防抖毫秒
retrynumber0失败重试次数
retryDelaynumber1000重试间隔毫秒

TIP

过期响应丢弃:同一 hook 实例内新一次 run 会作废未返回的旧请求结果(代次计数),配合分页翻页场景无需手写竞态判断。组件卸载自动作废在途请求回调;长轮询 / SSE 场景用 useWebSocket,分页状态管理用 usePagination。