Fetch and cache data with the useQuery composable. It returns a reactive query result that automatically updates when dependencies change.
Signature
function useQuery < TQueryFnData , TError , TData , TQueryKey >(
options : UseQueryOptions < TQueryFnData , TError , TData , TQueryKey >,
queryClient ?: QueryClient ,
) : UseQueryReturnType < TData , TError >
Parameters
options
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>
required
Configuration options for the query. Can be a reactive ref or getter function. queryKey
MaybeRefDeep<QueryKey>
required
Unique identifier for the query. Can be a ref or contain refs.
queryFn
MaybeRefDeep<QueryFunction>
required
Function that fetches the data. Can be a ref.
enabled
MaybeRefOrGetter<boolean>
Set to false to disable automatic query execution. Supports refs and getters.
Time in milliseconds until cached data is considered stale. Can be a ref.
Time in milliseconds before unused data is garbage collected. Can be a ref.
refetchInterval
MaybeRefDeep<number | false>
Interval in milliseconds for automatic refetching. Can be a ref.
Refetch when window regains focus. Can be a ref.
Refetch when network reconnects. Can be a ref.
retry
MaybeRefDeep<number | boolean>
Number of retry attempts or boolean to enable/disable retries. Can be a ref.
select
MaybeRefDeep<(data: TQueryData) => TData>
Transform or select a part of the data. Can be a ref.
initialData
MaybeRefDeep<TData | () => TData>
Initial data to use before the query executes. Can be a ref.
placeholderData
MaybeRefDeep<TData | () => TData>
Placeholder data while the query is loading. Can be a ref.
Return data in a shallow ref (improves performance if data doesn’t need deep reactivity).
Custom QueryClient instance. If not provided, uses the client from context.
Returns
UseQueryReturnType<TData, TError>
Reactive refs containing query state and methods. The query result data. Returns undefined if not yet loaded.
The error object if the query failed.
true when fetching for the first time (no cached data).
true whenever the query is fetching (including background refetches).
true when the query has successfully fetched data.
true when the query encountered an error.
true when the query is pending (no data and no error yet).
status
Ref<'pending' | 'error' | 'success'>
The current status of the query.
fetchStatus
Ref<'fetching' | 'paused' | 'idle'>
The fetch status of the query.
refetch
() => Promise<QueryObserverResult>
Manually trigger a refetch of the query.
Type Parameters
TQueryFnData - Type returned by the query function
TError - Type of error (defaults to DefaultError)
TData - Type of data returned (defaults to TQueryFnData)
TQueryKey - Type of the query key (defaults to QueryKey)
Examples
Basic Usage
< script setup >
import { useQuery } from '@tanstack/vue-query'
const { data , isLoading , error } = useQuery ({
queryKey: [ 'todos' ],
queryFn : async () => {
const res = await fetch ( '/api/todos' )
return res . json ()
},
})
</ script >
< template >
< div >
< div v-if = " isLoading " > Loading... </ div >
< div v-else-if = " error " > Error: {{ error . message }} </ div >
< ul v-else >
< li v-for = " todo in data " : key = " todo . id " >
{{ todo . title }}
</ li >
</ ul >
</ div >
</ template >
Reactive Query Keys
< script setup >
import { ref } from 'vue'
import { useQuery } from '@tanstack/vue-query'
const todoId = ref ( 1 )
// Query automatically refetches when todoId changes
const { data } = useQuery ({
queryKey: [ 'todo' , todoId ], // ref is auto-unwrapped
queryFn : async () => {
const res = await fetch ( `/api/todos/ ${ todoId . value } ` )
return res . json ()
},
})
</ script >
< template >
< div >
< button @ click = " todoId ++ " > Next Todo </ button >
< div v-if = " data " > {{ data . title }} </ div >
</ div >
</ template >
With TypeScript
< script setup lang = "ts" >
import { useQuery } from '@tanstack/vue-query'
interface Todo {
id : number
title : string
completed : boolean
}
const { data } = useQuery ({
queryKey: [ 'todos' ],
queryFn : async () : Promise < Todo []> => {
const res = await fetch ( '/api/todos' )
return res . json ()
},
})
// data is typed as Ref<Todo[] | undefined>
</ script >
Conditional Fetching
< script setup >
import { ref } from 'vue'
import { useQuery } from '@tanstack/vue-query'
const userId = ref ( null )
const enabled = ref ( false )
const { data } = useQuery ({
queryKey: [ 'user' , userId ],
queryFn : () => fetchUser ( userId . value ),
enabled , // Query only runs when enabled is true
})
</ script >
With Select
< script setup >
import { useQuery } from '@tanstack/vue-query'
const { data } = useQuery ({
queryKey: [ 'todos' ],
queryFn: fetchTodos ,
select : ( todos ) => todos . filter ( todo => ! todo . completed ),
})
// data only contains incomplete todos
</ script >
Shallow Reactivity
< script setup >
import { useQuery } from '@tanstack/vue-query'
// Use shallow: true for large datasets to improve performance
const { data } = useQuery ({
queryKey: [ 'large-dataset' ],
queryFn: fetchLargeDataset ,
shallow: true , // Prevents deep reactivity
})
</ script >