10 KiB
id, title
| id | title |
|---|---|
| useQuery | useQuery |
Call Signature
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): UseQueryDefinedReturnType<TData, TError>;
Defined in: packages/vue-query/src/useQuery.ts:65
This overload is selected when initialData is set, so the resulting data is never undefined.
enabled tracks reactive dependencies automatically as a ref, a plain value, or a reactive getter
(() => ...). queryKey reacts through a ref or a reactive getter for the array itself, or refs and
reactive getters as individual entries. Other options are read once when passed as a plain value, and stay
reactive when passed as a ref or a computed.
Type Parameters
TQueryFnData
TQueryFnData = unknown
TError
TError = Error
TData
TData = TQueryFnData
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
Parameters
options
DefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>
The DefinedInitialQueryOptions to use — everything you can pass to useQuery, with
initialData set.
queryClient?
Use this to use a custom QueryClient. Otherwise, the one provided by VueQueryPlugin
will be used.
Returns
UseQueryDefinedReturnType<TData, TError>
The current query result, typed so that data is never undefined (status never resolves to
pending in this overload's type, since initialData guarantees data upfront).
Example
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query'
// `data` is `Post[]`, never `undefined`, thanks to `initialData` — even if a refetch fails,
// so the list stays visible alongside the error.
const { data, isError, error } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
initialData: [],
})
</script>
<template>
<span v-if="isError">Error: {{ error.message }}</span>
<ul>
<li v-for="post in data" :key="post.id">{{ post.title }}</li>
</ul>
</template>
Call Signature
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): UseQueryReturnType<TData, TError>;
Defined in: packages/vue-query/src/useQuery.ts:206
enabled tracks reactive dependencies automatically as a ref, a plain value, or a reactive getter
(() => ...). queryKey reacts through a ref or a reactive getter for the array itself, or refs and
reactive getters as individual entries. Other options are read once when passed as a plain value, and stay
reactive when passed as a ref or a computed.
Type Parameters
TQueryFnData
TQueryFnData = unknown
TError
TError = Error
TData
TData = TQueryFnData
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
Parameters
options
UndefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>
The UndefinedInitialQueryOptions to use — everything you can pass to useQuery.
queryClient?
Use this to use a custom QueryClient. Otherwise, the one provided by VueQueryPlugin
will be used.
Returns
UseQueryReturnType<TData, TError>
The current query result. status is pending if there is no cached data to display, error if
the last fetch attempt failed, or success if the query has data to display.
Examples
A query key built from a reactive ref — the query refetches whenever postId changes:
<script setup lang="ts">
import { ref } from 'vue'
import { useQuery } from '@tanstack/vue-query'
const postId = ref(1)
const { status, data, error } = useQuery({
queryKey: ['post', postId],
queryFn: () => fetchPost(postId.value),
})
</script>
<template>
<span v-if="status === 'pending'">Loading...</span>
<span v-else-if="status === 'error'">Error: {{ error.message }}</span>
<h1 v-else>{{ data.title }}</h1>
</template>
select derives whatever data a component needs from the cached value, without changing what's
actually stored in the cache — the cache still holds the full Post[], but data here is a number:
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query'
const { data, isPending, isError, error } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
select: (posts) => posts.length,
})
</script>
<template>
<span v-if="isPending">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<span v-else>{{ data }} posts</span>
</template>
A dependent query, only enabled once postId is set — use isLoading, not isPending, so the
loading state doesn't show while the query is disabled:
<script setup lang="ts">
import { ref } from 'vue'
import { useQuery } from '@tanstack/vue-query'
const props = defineProps<{ postId: number | undefined }>()
const { data, isLoading, isError, error } = useQuery({
queryKey: ['post', props.postId],
queryFn: () => fetchPost(props.postId!),
enabled: () => props.postId != null,
})
</script>
<template>
<span v-if="props.postId == null">Select a post</span>
<span v-else-if="isLoading">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<h1 v-else>{{ data?.title }}</h1>
</template>
Seeding a detail query from an already-cached list, to skip the loading state:
<script setup lang="ts">
import { useQuery, useQueryClient } from '@tanstack/vue-query'
const props = defineProps<{ postId: number }>()
const queryClient = useQueryClient()
const { data, isError, error } = useQuery({
queryKey: ['post', props.postId],
queryFn: () => fetchPost(props.postId),
initialData: () =>
queryClient
.getQueryData<Array<Post>>(['posts'])
?.find((post) => post.id === props.postId),
})
</script>
<template>
<span v-if="isError">Error: {{ error.message }}</span>
<h1 v-else>{{ data?.title }}</h1>
</template>
Paginated data, keeping the previous page's data visible while the next page loads:
<script setup lang="ts">
import { ref } from 'vue'
import { keepPreviousData, useQuery } from '@tanstack/vue-query'
const page = ref(0)
const { data, isPlaceholderData, isError, error } = useQuery({
queryKey: ['posts', page],
queryFn: () => fetchPosts(page.value),
placeholderData: keepPreviousData,
})
</script>
<template>
<span v-if="isError">Error: {{ error.message }}</span>
<template v-else>
<ul>
<li v-for="post in data" :key="post.id">{{ post.title }}</li>
</ul>
<button :disabled="isPlaceholderData" @click="page++">Next Page</button>
</template>
</template>
Call Signature
function useQuery<TQueryFnData, TError, TData, TQueryKey>(options, queryClient?): UseQueryReturnType<TData, TError>;
Defined in: packages/vue-query/src/useQuery.ts:282
Fallback overload for options whose initialData presence isn't statically known — for example, a
ref/reactive object built up conditionally, rather than a plain object literal. Prefer one of the other
overloads when possible, since they infer whether data can be undefined from initialData directly.
enabled tracks reactive dependencies automatically as a ref, a plain value, or a reactive getter
(() => ...). queryKey reacts through a ref or a reactive getter for the array itself, or refs and
reactive getters as individual entries.
When options itself is a reactive getter, the whole object is re-evaluated on every change to its
dependencies, so any option inside it — not just queryKey and enabled — can change over time.
Type Parameters
TQueryFnData
TQueryFnData = unknown
TError
TError = Error
TData
TData = TQueryFnData
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
Parameters
options
MaybeRefOrGetter<UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>>
A ref, plain value, or reactive getter resolving to the UseQueryOptions to use.
queryClient?
Use this to use a custom QueryClient. Otherwise, the one provided by VueQueryPlugin
will be used.
Returns
UseQueryReturnType<TData, TError>
The current query result, with data typed as possibly undefined.
Examples
Passing a whole-options getter so staleTime reacts to a setting stored elsewhere, not just queryKey:
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query'
const props = defineProps<{ id: number; staleTime: number }>()
const { data } = useQuery(() => ({
queryKey: ['post', props.id],
queryFn: () => fetchPost(props.id),
staleTime: props.staleTime,
}))
</script>
<template>
<h1 v-if="data">{{ data.title }}</h1>
</template>
skipToken disables the query in a type-safe way, without a non-null assertion on props.postId —
queryFn is only ever called when it's defined. The whole-options getter re-evaluates queryFn on every
change to props.postId. queryFn can also be a computed, but never a bare getter, since a function
there is the query function itself. refetch doesn't work while queryFn is skipToken — use
enabled: false instead if you need to trigger the query manually:
<script setup lang="ts">
import { skipToken, useQuery } from '@tanstack/vue-query'
const props = defineProps<{ postId: number | undefined }>()
const { data, isLoading, isError, error } = useQuery(() => {
const postId = props.postId
return {
queryKey: ['post', postId],
queryFn: postId != null ? () => fetchPost(postId) : skipToken,
}
})
</script>
<template>
<span v-if="props.postId == null">Select a post</span>
<span v-else-if="isLoading">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<h1 v-else>{{ data?.title }}</h1>
</template>