tanstack-vue-query-skilld
TanStack/query @tanstack/vue-query@5.100.9
Tags: alpha: 5.0.0-alpha.91, beta: 5.0.0-beta.35, rc: 5.0.0-rc.16
References: Docs
API Changes
This section documents version-specific API changes — prioritize recent major/minor releases.
-
BREAKING:
useQueries()returnsRef<T[]>instead ofReactive<T[]>— Vue 2.7+ compatibility fix that aligns with other composables. Destructuring return value now requires unwrapping ref or usingtoRefs(). Update:const { data } = useQueries(...)becomesconst { data } = useQueries(...).valueorconst { data } = toRefs(useQueries(...))[0]source -
NEW: Composables support
injectionContext—useQuery,useMutation, and other composables can now run in functions with injection context (e.g., router navigation guards), not just componentsetup(). Must use withineffectScopeto prevent memory leaks source -
NEW: Options getter functions in
useQuery— pass reactive getters toqueryKeyandenabledoptions to track changes withoutcomputed(). Example:useQuery({ queryKey: () => ['posts', userId.value], enabled: () => isReady.value })source -
NEW: Options getter functions extended to additional composables —
useInfiniteQuery,useMutation,usePrefetchQuery, andusePrefetchInfiniteQuerynow support reactive getters for all reactive options source -
NEW:
enableDevtoolsV6Pluginoption for Traditional Devtools — integrate with Vue DevTools v6+ for custom inspector and timeline events. Enable:app.use(VueQueryPlugin, { enableDevtoolsV6Plugin: true }). Both v6 and v7 supported source -
EXPERIMENTAL:
experimental_createQueryPersister— persist individual queries to storage (AsyncStorage, LocalStorage, custom). Separate package@tanstack/query-persist-client-core. IncludespersistQueryByKey(),retrieveQuery(),restoreQueries(),persisterGc()utilities. RespectsstaleTimeon restore source -
EXPERIMENTAL:
broadcastQueryClientplugin — sync query cache across browser tabs and windows via message broadcasting. Experimental API, separate package, subject to change source
Also changed: Vue 3.3+ now required (was 3.x) · suspense() method on useQuery return for explicit await · VueQueryPlugin initialization unchanged · Query options now support getters alongside refs and values
Best Practices
-
Always use
queryOptions()helper when defining query configurations, rather than passing objects directly touseQuery— this enables TypeScript inference, prevents queryKey/queryFn mismatches at runtime, and allows safe reuse withqueryClientmethods likegetQueryData()andinvalidateQueries()source -
Pass reactive values (Ref or computed) directly into the
queryKeyarray, not their.value— Vue Query automatically tracks reactive dependencies and refetches when they change source -
Accept
MaybeRefOrGetter<T>in composable parameters instead of string values — this allows callers to pass refs, plain values, or reactive getters (() => props.userId) without wrapper code, giving maximum flexibility source -
Use
computed(() => props.property)for derived state from component props, not direct property access — property access on reactive objects loses reactivity, but computed captures it in the query's reactive tracking source -
Include all external variables used in
queryFnin thequeryKey— treat the query key like a dependency array; missing dependencies cause stale data and prevent proper cache invalidation source -
Create a single
QueryClientinstance at app initialization, not inside components — the client holds the cache for the entire app lifecycle, and recreating it loses all cached data source -
Destructure only the fields you actually use from query results; avoid object rest destructuring (
...rest) — rest destructuring subscribes to all fields, triggering unnecessary re-renders on any cache change source -
Use
skipTokenin acomputedqueryFnfor conditional queries instead ofenabled— this is more elegant for complex conditions and makes the intent clearer that the query should not run at all source -
Provide
placeholderDataas a function that queries other cache entries — this allows rendering stale detail data while fresh data loads, creating seamless UX transitions source -
Set
gcTime: Infinityin server-side QueryClient defaults to prevent memory accumulation — the server creates isolated clients per request and should rely on automatic cleanup rather than manual garbage collection source -
Use
queryClient.setMutationDefaults()to define default mutation functions keyed bymutationKey— this enables persisted mutations to resume after a page reload by replaying the same function source -
Call
toRefs()on the result ofuseQuerieswithcombinebefore destructuring — the combined result is wrapped in a Ref for Vue 2 compatibility, and destructuring directly loses reactivity source -
Prefetch infinite query pages with the
pagesoption and providegetNextPageParam— this pre-fills multiple pages into the cache, reducing pagination load states and waterfalls source -
Use a
computed()expression for theenabledoption when the condition depends on reactive state — this keeps the query automatically in sync with changing conditions without manual tracking source
More from harlan-zw/vue-ecosystem-skills
pinia-skilld
Intuitive, type safe and flexible Store for Vue. ALWAYS use when writing code importing \"pinia\". Consult for debugging, best practices, or modifying pinia.
159vue-i18n-skilld
Internationalization plugin for Vue.js. ALWAYS use when writing code importing \"vue-i18n\". Consult for debugging, best practices, or modifying vue-i18n, vue i18n.
154shadcn-vue-skilld
Add components to your apps. ALWAYS use when writing code importing \"shadcn-vue\". Consult for debugging, best practices, or modifying shadcn-vue, shadcn vue.
106floating-ui-vue-skilld
Floating UI for Vue. ALWAYS use when writing code importing \"@floating-ui/vue\". Consult for debugging, best practices, or modifying @floating-ui/vue, floating-ui/vue, floating-ui vue, floating ui vue, floating-ui, floating ui.
63unovis-vue-skilld
Modular data visualization framework for React, Angular, Svelte, Vue, and vanilla TypeScript or JavaScript. ALWAYS use when writing code importing \"@unovis/vue\". Consult for debugging, best practices, or modifying @unovis/vue, unovis/vue, unovis vue, unovis.
62