主题
useFetch
Reactive 获取 API 提供了中止请求、在触发请求之前拦截请求、在 url 更改时自动重新获取请求以及使用预定义选项创建你自己的 useFetch
的函数。
¥Reactive Fetch API provides the ability to abort requests, intercept requests before they are fired, automatically refetch requests when the url changes, and create your own useFetch
with predefined options.
提示
当与 Nuxt 3 一起使用时,该函数不会自动导入,而是使用 Nuxt 的内置 useFetch()
。如果你想使用 VueUse 中的函数,请使用显式导入。
¥When using with Nuxt 3, this function will NOT be auto imported in favor of Nuxt's built-in useFetch()
. Use explicit import if you want to use the function from VueUse.
示例
The following URLs can be used to test different features of useFetch
Normal Request:
https://httpbin.org/get
Abort Request:
https://httpbin.org/delay/10
Response Error:
http://httpbin.org/status/500
isFinished: false isFetching: false canAbort: false statusCode: null error: null data: null
用法
¥Usage
基本用法
¥Basic Usage
只需提供 url 即可使用 useFetch
函数。url 可以是字符串或 ref
。data
对象将包含请求的结果,error
对象将包含任何错误,isFetching
对象将指示请求是否正在加载。
¥The useFetch
function can be used by simply providing a url. The url can be either a string or a ref
. The data
object will contain the result of the request, the error
object will contain any errors, and the isFetching
object will indicate if the request is loading.
ts
import { useFetch } from '@vueuse/core'
const { isFetching, error, data } = useFetch(url)
异步使用
¥Asynchronous Usage
也可以像正常获取一样等待 useFetch
请注意,每当组件是异步的时,无论使用它的组件都必须将该组件封装在 <Suspense>
标记中。你可以在 Vue 3 官方文档 中阅读有关 Suspense api 的更多信息
¥useFetch
can also be awaited just like a normal fetch. Note that whenever a component is asynchronous, whatever component that uses it must wrap the component in a <Suspense>
tag. You can read more about the suspense api in the Official Vue 3 Docs
ts
import { useFetch } from '@vueuse/core'
const { isFetching, error, data } = await useFetch(url)
URL 更改时重新获取
¥Refetching on URL change
使用 ref
作为 url 参数将允许 useFetch
函数在 url 更改时自动触发另一个请求。
¥Using a ref
for the url parameter will allow the useFetch
function to automatically trigger another request when the url is changed.
ts
const url = ref('https://my-api.com/user/1')
const { data } = useFetch(url, { refetch: true })
url.value = 'https://my-api.com/user/2' // Will trigger another request
防止立即触发请求
¥Prevent request from firing immediately
将 immediate
选项设置为 false 将阻止触发请求,直到调用 execute
函数为止。
¥Setting the immediate
option to false will prevent the request from firing until the execute
function is called.
ts
const { execute } = useFetch(url, { immediate: false })
execute()
中止请求
¥Aborting a request
可以通过使用 useFetch
函数中的 abort
函数来中止请求。canAbort
属性指示是否可以中止请求。
¥A request can be aborted by using the abort
function from the useFetch
function. The canAbort
property indicates if the request can be aborted.
ts
const { abort, canAbort } = useFetch(url)
setTimeout(() => {
if (canAbort.value)
abort()
}, 100)
还可以使用 timeout
属性自动中止请求。当达到给定的超时时,它将调用 abort
函数。
¥A request can also be aborted automatically by using timeout
property. It will call abort
function when the given timeout is reached.
ts
const { data } = useFetch(url, { timeout: 100 })
拦截请求
¥Intercepting a request
beforeFetch
选项可以在请求发送之前拦截请求并修改请求选项和 url。
¥The beforeFetch
option can intercept a request before it is sent and modify the request options and url.
ts
const { data } = useFetch(url, {
async beforeFetch({ url, options, cancel }) {
const myToken = await getMyToken()
if (!myToken)
cancel()
options.headers = {
...options.headers,
Authorization: `Bearer ${myToken}`,
}
return {
options,
}
},
})
afterFetch
选项可以在更新之前拦截响应数据。
¥The afterFetch
option can intercept the response data before it is updated.
ts
const { data } = useFetch(url, {
afterFetch(ctx) {
if (ctx.data.title === 'HxH')
ctx.data.title = 'Hunter x Hunter' // Modifies the response data
return ctx
},
})
当 updateDataOnError
设置为 true
时,onFetchError
选项可以在更新之前拦截响应数据和错误。
¥The onFetchError
option can intercept the response data and error before it is updated when updateDataOnError
is set to true
.
ts
const { data } = useFetch(url, {
updateDataOnError: true,
onFetchError(ctx) {
// ctx.data can be null when 5xx response
if (ctx.data === null)
ctx.data = { title: 'Hunter x Hunter' } // Modifies the response data
ctx.error = new Error('Custom Error') // Modifies the error
return ctx
},
})
console.log(data.value) // { title: 'Hunter x Hunter' }
设置请求方法和返回类型
¥Setting the request method and return type
可以通过在 useFetch
末尾添加适当的方法来设置请求方法和返回类型
¥The request method and return type can be set by adding the appropriate methods to the end of useFetch
ts
// Request will be sent with GET method and data will be parsed as JSON
const { data } = useFetch(url).get().json()
// Request will be sent with POST method and data will be parsed as text
const { data } = useFetch(url).post().text()
// Or set the method using the options
// Request will be sent with GET method and data will be parsed as blob
const { data } = useFetch(url, { method: 'GET' }, { refetch: true }).blob()
创建自定义实例
¥Creating a Custom Instance
createFetch
函数将返回一个 useFetch 函数,其中包含提供给它的任何预配置选项。这对于在使用相同基本 URL 或需要授权标头的整个应用中与 API 进行交互非常有用。
¥The createFetch
function will return a useFetch function with whatever pre-configured options that are provided to it. This is useful for interacting with API's throughout an application that uses the same base URL or needs Authorization headers.
ts
const useMyFetch = createFetch({
baseUrl: 'https://my-api.com',
options: {
async beforeFetch({ options }) {
const myToken = await getMyToken()
options.headers.Authorization = `Bearer ${myToken}`
return { options }
},
},
fetchOptions: {
mode: 'cors',
},
})
const { isFetching, error, data } = useMyFetch('users')
如果你想控制预配置实例和新生成的实例之间 beforeFetch
、afterFetch
、onFetchError
的行为。你可以提供 combination
选项以在 overwrite
或 chaining
之间切换。
¥If you want to control the behavior of beforeFetch
, afterFetch
, onFetchError
between the pre-configured instance and newly spawned instance. You can provide a combination
option to toggle between overwrite
or chaining
.
ts
const useMyFetch = createFetch({
baseUrl: 'https://my-api.com',
combination: 'overwrite',
options: {
// beforeFetch in pre-configured instance will only run when the newly spawned instance do not pass beforeFetch
async beforeFetch({ options }) {
const myToken = await getMyToken()
options.headers.Authorization = `Bearer ${myToken}`
return { options }
},
},
})
// use useMyFetch beforeFetch
const { isFetching, error, data } = useMyFetch('users')
// use custom beforeFetch
const { isFetching, error, data } = useMyFetch('users', {
async beforeFetch({ url, options, cancel }) {
const myToken = await getMyToken()
if (!myToken)
cancel()
options.headers = {
...options.headers,
Authorization: `Bearer ${myToken}`,
}
return {
options,
}
},
})
活动
¥Events
onFetchResponse
和 onFetchError
将分别在获取请求响应和错误时触发。
¥The onFetchResponse
and onFetchError
will fire on fetch request responses and errors respectively.
ts
const { onFetchResponse, onFetchError } = useFetch(url)
onFetchResponse((response) => {
console.log(response.status)
})
onFetchError((error) => {
console.error(error.message)
})
类型声明
显示类型声明
typescript
export interface UseFetchReturn<T> {
/**
* Indicates if the fetch request has finished
*/
isFinished: Readonly<Ref<boolean>>
/**
* The statusCode of the HTTP fetch response
*/
statusCode: Ref<number | null>
/**
* The raw response of the fetch response
*/
response: Ref<Response | null>
/**
* Any fetch errors that may have occurred
*/
error: Ref<any>
/**
* The fetch response body on success, may either be JSON or text
*/
data: Ref<T | null>
/**
* Indicates if the request is currently being fetched.
*/
isFetching: Readonly<Ref<boolean>>
/**
* Indicates if the fetch request is able to be aborted
*/
canAbort: ComputedRef<boolean>
/**
* Indicates if the fetch request was aborted
*/
aborted: Ref<boolean>
/**
* Abort the fetch request
*/
abort: Fn
/**
* Manually call the fetch
* (default not throwing error)
*/
execute: (throwOnFailed?: boolean) => Promise<any>
/**
* Fires after the fetch request has finished
*/
onFetchResponse: EventHookOn<Response>
/**
* Fires after a fetch request error
*/
onFetchError: EventHookOn
/**
* Fires after a fetch has completed
*/
onFetchFinally: EventHookOn
get: () => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
post: (
payload?: MaybeRefOrGetter<unknown>,
type?: string,
) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
put: (
payload?: MaybeRefOrGetter<unknown>,
type?: string,
) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
delete: (
payload?: MaybeRefOrGetter<unknown>,
type?: string,
) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
patch: (
payload?: MaybeRefOrGetter<unknown>,
type?: string,
) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
head: (
payload?: MaybeRefOrGetter<unknown>,
type?: string,
) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
options: (
payload?: MaybeRefOrGetter<unknown>,
type?: string,
) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
json: <JSON = any>() => UseFetchReturn<JSON> &
PromiseLike<UseFetchReturn<JSON>>
text: () => UseFetchReturn<string> & PromiseLike<UseFetchReturn<string>>
blob: () => UseFetchReturn<Blob> & PromiseLike<UseFetchReturn<Blob>>
arrayBuffer: () => UseFetchReturn<ArrayBuffer> &
PromiseLike<UseFetchReturn<ArrayBuffer>>
formData: () => UseFetchReturn<FormData> &
PromiseLike<UseFetchReturn<FormData>>
}
type Combination = "overwrite" | "chain"
export interface BeforeFetchContext {
/**
* The computed url of the current request
*/
url: string
/**
* The request options of the current request
*/
options: RequestInit
/**
* Cancels the current request
*/
cancel: Fn
}
export interface AfterFetchContext<T = any> {
response: Response
data: T | null
}
export interface OnFetchErrorContext<T = any, E = any> {
error: E
data: T | null
}
export interface UseFetchOptions {
/**
* Fetch function
*/
fetch?: typeof window.fetch
/**
* Will automatically run fetch when `useFetch` is used
*
* @default true
*/
immediate?: boolean
/**
* Will automatically refetch when:
* - the URL is changed if the URL is a ref
* - the payload is changed if the payload is a ref
*
* @default false
*/
refetch?: MaybeRefOrGetter<boolean>
/**
* Initial data before the request finished
*
* @default null
*/
initialData?: any
/**
* Timeout for abort request after number of millisecond
* `0` means use browser default
*
* @default 0
*/
timeout?: number
/**
* Allow update the `data` ref when fetch error whenever provided, or mutated in the `onFetchError` callback
*
* @default false
*/
updateDataOnError?: boolean
/**
* Will run immediately before the fetch request is dispatched
*/
beforeFetch?: (
ctx: BeforeFetchContext,
) =>
| Promise<Partial<BeforeFetchContext> | void>
| Partial<BeforeFetchContext>
| void
/**
* Will run immediately after the fetch request is returned.
* Runs after any 2xx response
*/
afterFetch?: (
ctx: AfterFetchContext,
) => Promise<Partial<AfterFetchContext>> | Partial<AfterFetchContext>
/**
* Will run immediately after the fetch request is returned.
* Runs after any 4xx and 5xx response
*/
onFetchError?: (ctx: {
data: any
response: Response | null
error: any
}) => Promise<Partial<OnFetchErrorContext>> | Partial<OnFetchErrorContext>
}
export interface CreateFetchOptions {
/**
* The base URL that will be prefixed to all urls unless urls are absolute
*/
baseUrl?: MaybeRefOrGetter<string>
/**
* Determine the inherit behavior for beforeFetch, afterFetch, onFetchError
* @default 'chain'
*/
combination?: Combination
/**
* Default Options for the useFetch function
*/
options?: UseFetchOptions
/**
* Options for the fetch request
*/
fetchOptions?: RequestInit
}
export declare function createFetch(
config?: CreateFetchOptions,
): typeof useFetch
export declare function useFetch<T>(
url: MaybeRefOrGetter<string>,
): UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
export declare function useFetch<T>(
url: MaybeRefOrGetter<string>,
useFetchOptions: UseFetchOptions,
): UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
export declare function useFetch<T>(
url: MaybeRefOrGetter<string>,
options: RequestInit,
useFetchOptions?: UseFetchOptions,
): UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>