From floating-ui-vue
Guides @pinia/colada usage for data fetching in Vue.js: implement useQuery/useInfiniteQuery, handle API changes, debug issues, apply best practices. Activates on '@pinia/colada' imports.
npx claudepluginhub skilld-dev/vue-ecosystem-skills --plugin floating-ui-vueThis skill uses the workspace's default tool permissions.
**Tags:** latest: 1.1.0
references/discussions/_INDEX.mdreferences/discussions/discussion-239.mdreferences/discussions/discussion-243.mdreferences/discussions/discussion-275.mdreferences/discussions/discussion-315.mdreferences/discussions/discussion-325.mdreferences/discussions/discussion-333.mdreferences/discussions/discussion-336.mdreferences/discussions/discussion-338.mdreferences/discussions/discussion-346.mdreferences/discussions/discussion-384.mdreferences/discussions/discussion-395.mdreferences/discussions/discussion-399.mdreferences/discussions/discussion-417.mdreferences/discussions/discussion-419.mdreferences/discussions/discussion-421.mdreferences/discussions/discussion-426.mdreferences/discussions/discussion-428.mdreferences/discussions/discussion-438.mdreferences/discussions/discussion-484.mdProvides data fetching for Vue/Nuxt using Pinia Colada's useQuery and useMutation. Handles async state, query cache, SSR, invalidation, hydration errors, and TanStack Vue Query migrations.
Provides API reference, breaking changes, new features, and migration guides for TanStack Vue Query v5. Use when importing '@tanstack/vue-query' for data management, caching, and debugging.
Provides post-training cutoff knowledge on Vue 3.6 Vapor Mode (beta, direct DOM), Pinia 3/Colada, Vue Router 5 file-based routing, reactivity refactor, and data loaders for Vue.js work.
Share bugs, ideas, or general feedback.
@pinia/colada@1.1.0Tags: latest: 1.1.0
References: Docs
This section documents version-specific API changes — prioritize recent major/minor releases.
BREAKING: useInfiniteQuery() — v0.20.0 refactored: removed merge, changed data to { pages, pageParams }, initialPage → initialPageParam, loadMore → loadNextPage, and getNextPageParam is now required (experimental) source
BREAKING: PiniaColada installation — v0.14.0 moved global options to queryOptions: { ... } and requires an options object for typing: app.use(PiniaColada, {}) source
BREAKING: useQuery() aliases — isFetching was renamed to isLoading in v0.8.0 to better reflect its connection to asyncStatus source
BREAKING: Status split — v0.8.0 split status into status (data: 'pending'|'success'|'error') and asyncStatus (operation: 'idle'|'loading') source
BREAKING: Mutation IDs — v0.19.0 simplified mutation IDs to incremented numbers (starting at 1). mutationCache.get() now takes the ID, and $n suffix is removed from keys source
BREAKING: Cache Key structure — v0.16.0 refactored internal cache to support deeply nested objects for keys. toCacheKey now returns a plain string. Stricter types disallow undefined in keys source
BREAKING: queryCache method renames — cancelQuery() was renamed to cancel() in v0.11.0, and cancelQueries() was added for multiple cancellations source
BREAKING: setQueryState → setEntryState — v0.9.0 renamed this queryCache action to better match its purpose source
BREAKING: External AbortError — v0.18.0 now surfaces external abort signals as actual errors instead of silently ignoring them source
BREAKING: placeholderData types — v0.13.0 changed placeholderData to only allow returning undefined (not null) to improve type inference source
BREAKING: Devtools dependency — v0.21.0 removed built-in @vue/devtools-api dependency; use @pinia/colada-devtools instead source
NEW: useInfiniteQuery() — v0.13.5 introduced infinite scrolling support (experimental) source
NEW: useQueryState() — v0.17.0 added this for easier state management without the full useQuery return object source
NEW: Global Query Hooks — v0.8.0 introduced PiniaColadaQueryHooksPlugin to manage onSuccess, onError, and onSettled source
Also changed: serializeTreeMap replaces serialize v0.14.0 · transformError removed v0.12.0 · EntryKey replaces EntryNodeKey v0.17.0 · TResult renamed TData v0.16.0 · QueryPlugin → PiniaColada v0.8.0 · delayLoadingRef removed v0.12.0 · invalidateKeys moved to plugin v0.10.0
state object for type-safe narrowing in templates — TypeScript cannot narrow destructured data or error refs based on the status ref due to Vue's Ref wrapper limitations source<script setup lang="ts">
const { state } = useQuery({ key: ['user'], query: fetchUser })
</script>
<template>
<div v-if="state.status === 'success'">{{ state.data.name }}</div>
<div v-else-if="state.status === 'error'">{{ state.error.message }}</div>
</template>
defineQuery() to prevent desynchronization — regular composables recreate refs for each component instance, causing only the first component to successfully trigger key-based reactivity sourceexport const useFilteredTodos = defineQuery(() => {
const search = ref('')
const query = useQuery({
key: () => ['todos', { search: search.value }],
query: () => fetchTodos(search.value),
})
return { ...query, search }
})
defineQueryOptions() for strict type safety — this enables automatic type inference in queryCache methods without manual type casting or string-based key typos sourceexport const todoOptions = defineQueryOptions((id: string) => ({
key: ['todos', id],
query: () => fetchTodo(id),
}))
// Inferred TData: queryCache.getQueryData(todoOptions('1').key)
Handle side effects via watch or global plugins instead of query options — useQuery intentionally lacks onSuccess/onError to prevent side-effect duplication across multiple component instances source
Prefer refresh() over refetch() for standard UI updates — refresh() respects staleTime and deduplicates in-flight requests, whereas refetch() forces a network call regardless of cache status source
Use the meta property for declarative cross-cutting concerns — attach metadata to queries to drive global UI behavior (like toast messages) within the PiniaColadaQueryHooksPlugin source
Verify cache state before performing optimistic rollbacks — always check if the current cache value matches the optimistic value in onError to avoid overwriting concurrent successful updates from other mutations source
onError(err, vars, { newTodo, oldTodo }) {
if (newTodo === queryCache.getQueryData(['todos'])) {
queryCache.setQueryData(['todos'], oldTodo)
}
}
Use queryCache.setEntryState() for manual status synchronization — this is the preferred way to manually update an entry as setting data to undefined via setQueryData() is no longer supported for state resets source
Explicitly import useRoute from vue-router in Nuxt defineQuery definitions — the Nuxt auto-imported version can cause unnecessary query triggers or undefined values due to Suspense integration source
Use the enabled getter to guard "immortal" queries in global stores — prevents queries inside Pinia stores from making invalid network requests when required reactive parameters (like route params) are absent source
const result = useQuery({
key: () => ['deck', route.params.id],
query: () => fetchDeck(route.params.id),
enabled: () => !!route.params.id,
})