category |
---|
Network |
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.
::: tip
When using with Nuxt 3, this functions 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 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.
import { useFetch } from '@vueuse/core'
const { isFetching, error, data } = useFetch(url)
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 Offical Vue 3 Docs
import { useFetch } from '@vueuse/core'
const { isFetching, error, data } = await useFetch(url)
Using a ref
for the url parameter will allow the useFetch
function to automatically trigger another request when the url is changed.
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
Setting the immediate
option to false will prevent the request from firing until the execute
function is called.
const { execute } = useFetch(url, { immediate: false })
execute()
A request can be aborted by using the abort
function from the useFetch
function. The canAbort
property indicates if the request can be aborted.
const { abort, canAbort } = useFetch(url)
setTimeout(() => {
if (canAbort.value)
abort()
}, 100)
A request can also be aborted automatically by using timeout
property. It will call abort
function when the given timeout is reached.
const { data } = useFetch(url, { timeout: 100 })
The beforeFetch
option can intercept a request before it is sent and modify the request options and url.
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,
}
},
})
The afterFetch
option can intercept the response data before it is updated.
const { data } = useFetch(url, {
afterFetch(ctx) {
if (ctx.data.title === 'HxH')
ctx.data.title = 'Hunter x Hunter' // Modifies the response data
return ctx
},
})
The onFetchError
option can intercept the response data and error before it is updated.
const { data } = useFetch(url, {
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
},
})
The request method and return type can be set by adding the appropriate methods to the end of useFetch
// 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()
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.
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')
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
.
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,
}
},
})
The onFetchResponse
and onFetchError
will fire on fetch request responses and errors respectively.
const { onFetchResponse, onFetchError } = useFetch(url)
onFetchResponse((response) => {
console.log(response.status)
})
onFetchError((error) => {
console.error(error.message)
})