Skip to content

request

请求组合式函数,支持缓存和共享等功能。

导入

typescript
import { useRequest } from '@cloudcome/utils-vue/request';
import type {
  UseRequestOptions,
  RequestCacheOptions,
  RequestShareOptions,
  UseRequestState,
  UseRequestOutput,
} from '@cloudcome/utils-vue/request';

类型定义

UseRequestOptions<I, O>

typescript
interface UseRequestOptions<I extends AnyArray, O> extends UseAsyncOptions<I, O> {
  id?: MaybeCallable<string>;
  cache?: boolean | RequestCacheOptions<O>;
  share?: boolean | RequestShareOptions;
  onCacheHit?: (cached: Cached<O>) => unknown;
}

属性说明

属性类型描述
idMaybeCallable<string>请求 ID,用于缓存和共享
cacheboolean | RequestCacheOptions<O>缓存配置
shareboolean | RequestShareOptions共享配置
onCacheHit(cached: Cached<O>) => unknown缓存命中回调

RequestCacheOptions<T>

typescript
interface RequestCacheOptions<T> extends CacheOptions {
  disabled?: boolean;
  storage?: Cache<T>;
}

属性说明

属性类型描述
disabledboolean是否禁用缓存。设为 true 时每次请求都会重新执行
storageCache<T>自定义缓存存储,默认使用全局 MemoryCache
maxAgenumber缓存过期时间(毫秒)
expiredAtDateValue缓存过期时间点

RequestShareOptions

typescript
interface RequestShareOptions {
  disabled?: boolean;
  maxAge?: number;
  expiredAt?: DateValue;
}

属性说明

属性类型描述
disabledboolean是否禁用共享
maxAgenumber共享过期时间(毫秒)
expiredAtDateValue共享过期时间点

UseRequestState

typescript
interface UseRequestState {
  times: number;
  loading: boolean;
  error: unknown;
  hitShare: boolean;
  hitCache: boolean;
}

属性说明

属性类型描述
timesnumber已执行次数
loadingboolean是否正在加载
errorunknown错误信息,无错误时为 null
hitShareboolean是否命中共享请求
hitCacheboolean是否命中缓存

UseRequestOutput<I, O>

typescript
interface UseRequestOutput<I extends AnyArray, O> {
  state: ComputedRef<UseRequestState>
  loading: ComputedRef<boolean>
  data: ComputedRef<O | null>
  error: ComputedRef<unknown>
  send: (...inputs: I) => void
  sendAsync: (...inputs: I) => Promise<O>
  hitShare: Ref<boolean>
  hitCache: Ref<boolean>
}````

## 函数

### useRequest

创建请求组合式函数。

```typescript
function useRequest<I extends AnyArray, O>(
  fn: (...inputs: I) => Promise<O>,
  options?: UseRequestOptions<I, O>
): UseRequestOutput<I, O>
```

**参数**

| 参数    | 类型                           | 描述     |
| ------- | ------------------------------ | -------- |
| fn      | `(...inputs: I) => Promise<O>` | 请求函数 |
| options | `UseRequestOptions<I, O>`      | 可选配置 |

**返回值**

`UseRequestOutput<I, O>` - 请求状态和方法

**示例**

```typescript
// 基本用法
const { data, loading, error, send } = useRequest(async (id: string) => {
  const response = await fetch(`/api/users/${id}`)
  return response.json()
})

// 发送请求
send('123')

// 启用缓存
const { data, loading } = useRequest(
  async (id: string) => {
    const response = await fetch(`/api/users/${id}`)
    return response.json()
  },
  {
    id: 'user-detail',
    cache: {
      maxAge: 5 * 60 * 1000 // 5 分钟
    }
  }
)

// 启用共享
const { data, loading } = useRequest(
  async (id: string) => {
    const response = await fetch(`/api/users/${id}`)
    return response.json()
  },
  {
    id: 'user-detail',
    share: {
      maxAge: 10 * 1000 // 10 秒
    }
  }
)

// 监听缓存命中
const { data, loading } = useRequest(
  async (id: string) => {
    const response = await fetch(`/api/users/${id}`)
    return response.json()
  },
  {
    id: 'user-detail',
    cache: true,
    onCacheHit: (cached) => {
      console.log('Cache hit:', cached)
    }
  }
)

// 禁用缓存:即使 id 相同,每次请求都会重新执行
const { hitCache, sendAsync } = useRequest(
  async (id: string) => fetchUser(id),
  {
    id: 'user',
    cache: { disabled: true }
  }
)
await sendAsync('123')
await sendAsync('123')
// hitCache.value 始终为 false
// 请求函数被调用了 2 次

// 禁用共享:同步并发调用不会共享
const { hitShare, sendAsync } = useRequest(
  async () => fetchData(),
  {
    id: 'data',
    share: { disabled: true }
  }
)
const p1 = sendAsync()
const p2 = sendAsync()
await Promise.all([p1, p2])
// hitShare.value 为 false
// 请求函数被调用了 2 次

// 同步并发调用命中共享
const fn = async () => {
  await new Promise(r => setTimeout(r, 50))
  return { id: 1 }
}
const { hitShare: hs1, sendAsync: s1 } = useRequest(fn, {
  id: 'sync-test',
  share: true
})
const { hitShare: hs2, sendAsync: s2 } = useRequest(fn, {
  id: 'sync-test',
  share: true
})
const p1 = s1()
const p2 = s2() // 同步调用,共享尚未完成
await Promise.all([p1, p2])
// hs1.value = false(首次发起请求)
// hs2.value = true(命中共享的 Promise)
// fn 只被调用 1 次

// 不同 id 的请求不共享
const { hitShare: hs1 } = useRequest(fn, { id: 'id-1', share: true })
const { hitShare: hs2 } = useRequest(fn, { id: 'id-2', share: true })
await Promise.all([s1(), s2()])
// hs1.value = false, hs2.value = false
// fn 被调用 2 次

// 不传 id 时共享不生效
const { hitShare: hs1 } = useRequest(fn, { share: true })
const { hitShare: hs2 } = useRequest(fn, { share: true })
await Promise.all([s1(), s2()])
// hs1.value = false, hs2.value = false
// fn 被调用 2 次

// 共享与缓存同时使用,互不干扰
const { hitShare: hs, hitCache: hc, sendAsync } = useRequest(fn, {
  id: 'both',
  share: true,
  cache: true
})
// 首次调用:hs = false, hc = false
// 第二次调用(缓存已存在):hs = false, hc = true
```

基于 MIT 许可发布