### Install Vue Query Devtools Source: https://tanstack.com/query/latest/docs/framework/vue/devtools.md Install the devtools package using your preferred package manager. ```bash npm i @tanstack/vue-query-devtools ``` ```bash pnpm add @tanstack/vue-query-devtools ``` ```bash yarn add @tanstack/vue-query-devtools ``` ```bash bun add @tanstack/vue-query-devtools ``` -------------------------------- ### Install Dependencies for Nuxt 3 Source: https://tanstack.com/query/latest/docs/framework/vue/examples/nuxt3 Install project dependencies using pnpm. This is a required step before running the development server. ```bash pnpm install ``` -------------------------------- ### Basic Mutation Setup - React Source: https://tanstack.com/query/latest/docs/framework/vue/guides/invalidations-from-mutations.md Sets up a basic mutation function using `useMutation`. ```tsx const mutation = useMutation({ mutationFn: postTodo }) ``` -------------------------------- ### Start Nuxt 3 Development Server Source: https://tanstack.com/query/latest/docs/framework/vue/examples/nuxt3 Start the Nuxt 3 development server to view your application locally. The server runs on http://localhost:3000. ```bash pnpm dev ``` -------------------------------- ### Basic Paginated Query Example (React) Source: https://tanstack.com/query/latest/docs/framework/vue/guides/paginated-queries.md This basic example shows how to fetch paginated data using `useQuery` with the page number in the query key. It highlights the potential UI jumping issue between success and pending states. ```tsx const result = useQuery({ queryKey: ['projects', page], queryFn: () => fetchProjects(page), }) ``` -------------------------------- ### Fetch API Example for Infinite Queries Source: https://tanstack.com/query/latest/docs/framework/vue/guides/infinite-queries.md Demonstrates the structure of API responses for paginated data, including the data payload and the next cursor for subsequent requests. ```bash fetch('/api/projects?cursor=0') // { data: [...], nextCursor: 3} fetch('/api/projects?cursor=3') // { data: [...], nextCursor: 6} fetch('/api/projects?cursor=6') // { data: [...], nextCursor: 9} fetch('/api/projects?cursor=9') // { data: [...] } ``` -------------------------------- ### Use Query with Fetch Function Source: https://tanstack.com/query/latest/docs/framework/vue/guides/caching.md This is a basic example of how to use the `useQuery` hook to fetch and cache data. It assumes `fetchTodos` is defined elsewhere and returns a Promise. ```javascript useQuery({ queryKey: ['todos'], queryFn: fetchTodos }) ``` -------------------------------- ### Provide Custom QueryClient Instance with Custom Context Key Source: https://tanstack.com/query/latest/docs/framework/vue/guides/custom-client.md Combine providing a custom QueryClient instance with a custom context key for advanced setup scenarios. ```typescript const myClient = new QueryClient(queryClientConfig) const vueQueryPluginOptions: VueQueryPluginOptions = { queryClient: myClient, queryClientKey: 'Foo', } app.use(VueQueryPlugin, vueQueryPluginOptions) ``` -------------------------------- ### Simplified OnSettled Handler Source: https://tanstack.com/query/latest/docs/framework/vue/guides/optimistic-updates.md The `onSettled` handler can be used to perform actions after a mutation, whether it succeeds or fails. This example shows a basic check for an error. ```tsx useMutation({ mutationFn: updateTodo, // ... onSettled: async (newTodo, error, variables, onMutateResult, context) => { if (error) { // do something } }, }) ``` -------------------------------- ### Vue Infinite Query Implementation Source: https://tanstack.com/query/latest/docs/framework/vue/guides/infinite-queries.md Sets up useInfiniteQuery in Vue to fetch paginated project data. It configures the query function, initial page parameter, and how to get the next page parameter from the API response. ```vue ``` -------------------------------- ### Refetch Active Queries by Key Source: https://tanstack.com/query/latest/docs/framework/vue/guides/filters.md Refetch active queries whose keys start with 'posts'. Combine `queryKey` and `type: 'active'` for precise targeting. ```typescript await queryClient.refetchQueries({ queryKey: ['posts'], type: 'active' }) ``` -------------------------------- ### useQuery Dependent Query Example Source: https://tanstack.com/query/latest/docs/framework/vue/guides/dependent-queries.md Use the `enabled` option to control when a query executes. The dependent query will only run after the initial query successfully fetches data and its `userId` is available. ```javascript // Get the user const { data: user } = useQuery({ queryKey: ['user', email], queryFn: () => getUserByEmail(email.value), }) const userId = computed(() => user.value?.id) const enabled = computed(() => !!user.value?.id) // Then get the user's projects const { isIdle, data: projects } = useQuery({ queryKey: ['projects', userId], queryFn: () => getProjectsByUser(userId.value), enabled, // The query will not execute until `enabled == true` }) ``` -------------------------------- ### Handling Simultaneous Fetches in Infinite Queries Source: https://tanstack.com/query/latest/docs/framework/vue/guides/infinite-queries.md Provides an example of how to trigger fetching the next page when the user reaches the end of a list, while also preventing simultaneous fetches to avoid data overwrites. ```jsx hasNextPage && !isFetching && fetchNextPage()} /> ``` -------------------------------- ### Run Codemod for JS/JSX Files Source: https://tanstack.com/query/latest/docs/framework/vue/guides/migrating-to-v5.md Use this command to run the v5 codemod on JavaScript and JSX files. Ensure you have jscodeshift installed. ```bash npx jscodeshift@latest ./path/to/src/ \ --extensions=js,jsx \ --transform=./node_modules/@tanstack/react-query/build/codemods/src/v5/remove-overloads/remove-overloads.cjs ``` -------------------------------- ### Vue Query Plugin for Nuxt 2 Source: https://tanstack.com/query/latest/docs/framework/vue/guides/ssr.md Create a vue-query.js plugin in your plugins directory to initialize Vue Query with SSR support. This setup handles the QueryClient instantiation and hydration on both server and client. ```javascript import Vue from 'vue' import { VueQueryPlugin, QueryClient, hydrate } from '@tanstack/vue-query' export default (context) => { // Modify your Vue Query global settings here const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 5000 } }, }) if (process.server) { context.ssrContext.VueQuery = queryClient } if (process.client) { Vue.use(VueQueryPlugin, { queryClient }) if (context.nuxtState && context.nuxtState.vueQueryState) { hydrate(queryClient, context.nuxtState.vueQueryState) } } } ``` ```javascript import Vue from 'vue' import { VueQueryPlugin, QueryClient, hydrate } from '@tanstack/vue-query' export default (context) => { // Modify your Vue Query global settings here const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 5000 } }, }) if (process.server) { context.ssrContext.VueQuery = queryClient } if (process.client) { Vue.use(VueQueryPlugin, { queryClient }) if (context.nuxtState && context.nuxtState.vueQueryState) { hydrate(queryClient, context.nuxtState.vueQueryState) } } } ``` -------------------------------- ### Configure Individual Query Retries Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-retries.md Set the number of times a specific query will retry upon failure. This example configures a query to retry up to 10 times. ```vue import { useQuery } from '@tanstack/vue-query' // Make a specific query retry a certain number of times const result = useQuery({ queryKey: ['todos', 1], queryFn: fetchTodoListPage, retry: 10, // Will retry failed requests 10 times before displaying an error }) ``` -------------------------------- ### useQueries Dependent Query Example Source: https://tanstack.com/query/latest/docs/framework/vue/guides/dependent-queries.md Dynamically create and execute multiple dependent queries using `useQueries`. The `queries` computed property generates the query configurations based on the result of a preceding query. ```typescript // Get the users ids const { data: userIds } = useQuery({ queryKey: ['users'], queryFn: getUsersData, select: (users) => users.map((user) => user.id), }) const queries = computed(() => { return userIds.value.length ? userIds.value.map((id) => { return { queryKey: ['messages', id], queryFn: () => getMessagesByUsers(id), } }) : [] }) // Then get the users messages const usersMessages = useQueries({ queries, // if userIds.value is undefined or has no items, an empty array will be returned }) ``` -------------------------------- ### Configure Fixed Retry Delay for Individual Query Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-retries.md Set a fixed delay for retrying a specific query. This example sets the retry delay to 1000ms for all retries of the 'todos' query. ```vue const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList, retryDelay: 1000, // Will always wait 1000ms to retry, regardless of how many retries }) ``` -------------------------------- ### Improved Paginated Queries with `keepPreviousData` (Vue) Source: https://tanstack.com/query/latest/docs/framework/vue/guides/paginated-queries.md This Vue.js example demonstrates using `placeholderData: keepPreviousData` to maintain the previous data while new data is being fetched, preventing UI jumps. The `isPlaceholderData` flag helps identify when previous data is being shown. ```vue ``` -------------------------------- ### Custom Background Retry Strategy Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-retries.md Implement a custom retry strategy when background refetching is enabled. This example disables built-in retries and uses `refetchInterval` to control retry timing, refetching more frequently when the query is in an error state. ```vue const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodos, refetchInterval: (query) => { // Refetch more frequently when in error state return query.state.status === 'error' ? 5000 : 30000 }, refetchIntervalInBackground: true, retry: false, // Disable built-in retries }) ``` -------------------------------- ### Define and Use a Persisted Mutation Source: https://tanstack.com/query/latest/docs/framework/vue/guides/mutations.md Defines a mutation with optimistic updates and persistence logic. It includes setup for `onMutate`, `onSuccess`, and `onError` callbacks, and demonstrates how to dehydrate and hydrate the query client state to persist mutations. Ensure `addTodo` and `uuid` are defined elsewhere. ```tsx const queryClient = new QueryClient() // Define the "addTodo" mutation queryClient.setMutationDefaults(['addTodo'], { mutationFn: addTodo, onMutate: async (variables, context) => { // Cancel current queries for the todos list await context.client.cancelQueries({ queryKey: ['todos'] }) // Create optimistic todo const optimisticTodo = { id: uuid(), title: variables.title } // Add optimistic todo to todos list context.client.setQueryData(['todos'], (old) => [...old, optimisticTodo]) // Return a result with the optimistic todo return { optimisticTodo } }, onSuccess: (result, variables, onMutateResult, context) => { // Replace optimistic todo in the todos list with the result context.client.setQueryData(['todos'], (old) => old.map((todo) => todo.id === onMutateResult.optimisticTodo.id ? result : todo, ), ) }, onError: (error, variables, onMutateResult, context) => { // Remove optimistic todo from the todos list context.client.setQueryData(['todos'], (old) => old.filter((todo) => todo.id !== onMutateResult.optimisticTodo.id), ) }, retry: 3, }) // Start mutation in some component: const mutation = useMutation({ mutationKey: ['addTodo'] }) mutation.mutate({ title: 'title' }) // If the mutation has been paused because the device is for example offline, // Then the paused mutation can be dehydrated when the application quits: const state = dehydrate(queryClient) // The mutation can then be hydrated again when the application is started: hydrate(queryClient, state) // Resume the paused mutations: queryClient.resumePausedMutations() ``` -------------------------------- ### Check Number of Fetching Mutations Source: https://tanstack.com/query/latest/docs/framework/vue/guides/filters.md Use `queryClient.isMutating()` without arguments to get the count of all mutations that are currently in a fetching state. ```typescript await queryClient.isMutating() ``` -------------------------------- ### Manual Parallel Queries with useQuery Source: https://tanstack.com/query/latest/docs/framework/vue/guides/parallel-queries.md Use multiple `useQuery` hooks side-by-side for a fixed number of parallel queries. Ensure all necessary functions like `fetchUsers`, `fetchTeams`, and `fetchProjects` are defined and imported. ```vue ``` -------------------------------- ### Invalidate Queries by Key Prefix Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-invalidation.md Invalidates queries whose keys start with a specified prefix. Useful for targeting related data. ```typescript queryClient.invalidateQueries({ queryKey: ['todos'] }) ``` -------------------------------- ### Invalidate Queries by Prefix Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-invalidation.md Use a query key prefix to invalidate all queries that start with that prefix. This is useful for invalidating a group of related queries. ```vue import { useQuery, useQueryClient } from '@tanstack/vue-query' // Get QueryClient from the context const queryClient = useQueryClient() queryClient.invalidateQueries({ queryKey: ['todos'] }) // Both queries below will be invalidated const todoListQuery = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList, }) const todoListQuery = useQuery({ queryKey: ['todos', { page: 1 }], queryFn: fetchTodoList, }) ``` -------------------------------- ### Prepopulate Query with initialData Source: https://tanstack.com/query/latest/docs/framework/vue/guides/initial-query-data.md Use the `initialData` option to provide data directly to a query, bypassing the initial loading state. Ensure the provided data is complete, as `initialData` is persisted to the cache. ```tsx const result = useQuery({ queryKey: ['todos'], queryFn: () => fetch('/todos'), initialData: initialTodos, }) ``` -------------------------------- ### Basic useQuery Hook Source: https://tanstack.com/query/latest/docs/framework/vue/guides/queries.md Import and use the useQuery hook with a unique query key and a function that returns a promise to fetch data. ```typescript import { useQuery } from '@tanstack/vue-query' const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList }) ``` ```typescript import { useQuery } from '@tanstack/vue-query' const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList }) ``` -------------------------------- ### Remove Inactive Queries by Key Source: https://tanstack.com/query/latest/docs/framework/vue/guides/filters.md Remove all inactive queries whose keys start with 'posts'. Specify `queryKey` and `type: 'inactive'` to target specific queries. ```typescript queryClient.removeQueries({ queryKey: ['posts'], type: 'inactive' }) ``` -------------------------------- ### Build Nuxt 3 Application for Production Source: https://tanstack.com/query/latest/docs/framework/vue/examples/nuxt3 Builds the Nuxt 3 application for deployment. This command generates optimized static assets and server code for production environments. ```bash pnpm build ``` -------------------------------- ### Vite SSR Entry Point with VueQuery Source: https://tanstack.com/query/latest/docs/framework/vue/guides/ssr.md Configure the Vite SSR entry point to initialize and synchronize VueQuery client state. This hook is called once per request. ```javascript // main.js (entry point) import App from './App.vue' import viteSSR from 'vite-ssr/vue' import { QueryClient, VueQueryPlugin, hydrate, dehydrate, } from '@tanstack/vue-query' export default viteSSR(App, { routes: [] }, ({ app, initialState }) => { // -- This is Vite SSR main hook, which is called once per request // Create a fresh VueQuery client const queryClient = new QueryClient() // Sync initialState with the client state if (import.meta.env.SSR) { // Indicate how to access and serialize VueQuery state during SSR initialState.vueQueryState = { toJSON: () => dehydrate(queryClient) } } else { // Reuse the existing state in the browser hydrate(queryClient, initialState.vueQueryState) } // Mount and provide the client to the app components app.use(VueQueryPlugin, { queryClient }) }) ``` -------------------------------- ### Multiple Query Function Configurations Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-functions.md Illustrates various ways to define query functions, including direct function calls, arrow functions, and async functions. ```tsx useQuery({ queryKey: ['todos'], queryFn: fetchAllTodos }) useQuery({ queryKey: ['todos', todoId], queryFn: () => fetchTodoById(todoId) }) useQuery({ queryKey: ['todos', todoId], queryFn: async () => { const data = await fetchTodoById(todoId) return data }, }) useQuery({ queryKey: ['todos', todoId], queryFn: ({ queryKey }) => fetchTodoById(queryKey[1]), }) ``` -------------------------------- ### Defining and using queryOptions Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-options.md This snippet shows how to define reusable query options using the `queryOptions` helper, including `queryKey`, `queryFn`, and `staleTime`. It then demonstrates various ways to use these options with different TanStack Query hooks and client methods. ```typescript import { queryOptions } from '@tanstack/vue-query' function groupOptions(id: number) { return queryOptions({ queryKey: ['groups', id], queryFn: () => fetchGroups(id), staleTime: 5 * 1000, }) } // usage: useQuery(groupOptions(1)) useSuspenseQuery(groupOptions(5)) useQueries({ queries: [groupOptions(1), groupOptions(2)], }) queryClient.prefetchQuery(groupOptions(23)) queryClient.setQueryData(groupOptions(42).queryKey, newGroups) ``` -------------------------------- ### Using mutateAsync for Promises Source: https://tanstack.com/query/latest/docs/framework/vue/guides/mutations.md Use `mutateAsync` to get a promise that resolves on success or throws on error, enabling composition of side effects and error handling with try/catch blocks. ```tsx const mutation = useMutation({ mutationFn: addTodo }) try { const todo = await mutation.mutateAsync(todo) console.log(todo) } catch (error) { console.error(error) } finally { console.log('done') } ``` -------------------------------- ### Simplified Optimistic Updates with useMutation Source: https://tanstack.com/query/latest/docs/framework/vue/guides/migrating-to-v5.md Demonstrates optimistic updates by leveraging the `variables` returned from `useMutation` to display pending data. This approach is suitable when optimistic updates are needed in a single UI location. ```tsx const queryInfo = useTodos() const addTodoMutation = useMutation({ mutationFn: (newTodo: string) => axios.post('/api/data', { text: newTodo }), onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }), }) if (queryInfo.data) { return ( ) } ``` -------------------------------- ### Prefetching Data on Server with Nuxt 3 Source: https://tanstack.com/query/latest/docs/framework/vue/guides/ssr.md Demonstrates how to prefetch data using `suspense()` within `onServerPrefetch` in a Nuxt 3 component. This ensures data is available when the component is rendered on the server. ```typescript export default defineComponent({ setup() { const { data, suspense } = useQuery({ queryKey: ['test'], queryFn: fetcher, }) onServerPrefetch(async () => { await suspense() }) return { data } }, }) ``` -------------------------------- ### Configure Global Retry Delay Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-retries.md Set a default retry delay for all queries using the Vue Query plugin. This example implements an exponential back-off delay, capping at 30 seconds. ```vue import { VueQueryPlugin } from '@tanstack/vue-query' const vueQueryPluginOptions = { queryClientConfig: { defaultOptions: { queries: { retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000), }, }, }, } app.use(VueQueryPlugin, vueQueryPluginOptions) ``` -------------------------------- ### Dynamic Parallel Queries with useQueries Source: https://tanstack.com/query/latest/docs/framework/vue/guides/parallel-queries.md Use the `useQueries` hook when the number of queries to execute changes dynamically between renders. It accepts an options object with a `queries` key, which is an array of query objects, and returns an array of query results. ```javascript const users = computed(...) const queries = computed(() => users.value.map(user => { return { queryKey: ['user', user.id], queryFn: () => fetchUserById(user.id), } }) ); const userQueries = useQueries({queries: queries}) ``` -------------------------------- ### Query Function with External Fetch Function Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-functions.md Shows how to use an external function as a query function, accessing query key variables within it. ```js const result = useQuery({ queryKey: ['todos', { status, page }], queryFn: fetchTodoList, }) // Access the key, status and page variables in your query function! function fetchTodoList({ queryKey }) { const [_key, { status, page }] = queryKey return new Promise() } ``` -------------------------------- ### Nuxt 3 Vue Query Plugin Setup Source: https://tanstack.com/query/latest/docs/framework/vue/guides/ssr.md This plugin configures Vue Query for Nuxt 3, handling the dehydration of query states on the server and hydration on the client. It allows for global configuration of the QueryClient. ```typescript import type { DehydratedState, VueQueryPluginOptions, } from '@tanstack/vue-query' import { VueQueryPlugin, QueryClient, hydrate, dehydrate, } from '@tanstack/vue-query' // Nuxt 3 app aliases import { defineNuxtPlugin, useState } from '#imports' export default defineNuxtPlugin((nuxt) => { const vueQueryState = useState('vue-query') // Modify your Vue Query global settings here const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 5000 } }, }) const options: VueQueryPluginOptions = { queryClient } nuxt.vueApp.use(VueQueryPlugin, options) if (import.meta.server) { nuxt.hooks.hook('app:rendered', () => { vueQueryState.value = dehydrate(queryClient) }) } if (import.meta.client) { hydrate(queryClient, vueQueryState.value) } }) ``` -------------------------------- ### Initial Data from Cache Source: https://tanstack.com/query/latest/docs/framework/vue/guides/initial-query-data.md Use `queryClient.getQueryData` within a function passed to `initialData` to populate a query with data from another cached query. This is helpful for scenarios like fetching an individual item based on data from a list query. ```tsx const result = useQuery({ queryKey: ['todo', todoId], queryFn: () => fetch('/todos'), initialData: () => { // Use a todo from the 'todos' query as the initial data for this todo query return queryClient.getQueryData(['todos'])?.find((d) => d.id === todoId) }, }) ``` -------------------------------- ### Provide custom queryClient instance Source: https://tanstack.com/query/latest/docs/framework/vue/guides/migrating-to-v5.md Replace the custom `context` prop with a custom `queryClient` instance for better isolation and framework-agnostic functionality. ```tsx import { queryClient } from './my-client' const { data } = useQuery( { queryKey: ['users', id], queryFn: () => fetch(...), }, queryClient, ) ``` -------------------------------- ### Initial Data with staleTime Source: https://tanstack.com/query/latest/docs/framework/vue/guides/initial-query-data.md Configuring `initialData` with a `staleTime` (e.g., 1000ms) prevents the query from refetching until after that duration has passed since the component mounted, assuming no other interaction events occur. ```tsx const result = useQuery({ queryKey: ['todos'], queryFn: () => fetch('/todos'), initialData: initialTodos, staleTime: 1000, }) ``` -------------------------------- ### Disable Query with `enabled: false` in Vue Source: https://tanstack.com/query/latest/docs/framework/vue/guides/disabling-queries.md Use `enabled: false` to prevent a query from automatically fetching on mount or refetching in the background. Manual fetching can be triggered using the `refetch` function. This option initializes the query with cached data if available, otherwise it starts in a pending state. ```vue ``` -------------------------------- ### Nuxt 3 Production Dependencies Source: https://tanstack.com/query/latest/docs/framework/vue/examples/nuxt3 This snippet shows the production dependencies for a Nuxt 3 project, including tools like @clack/prompts, consola, diff, execa, magicast, pathe, pkg-types, and semver. It also defines a binary script for devtools-wizard. ```json { "name": "@nuxt/devtools", "version": "0.0.0", "private": true, "type": "module", "packageManager": "pnpm@8.15.4", "scripts": { "dev": "nr --filter @nuxt/devtools dev", "build": "nr --filter @nuxt/devtools build", "generate": "nr --filter @nuxt/devtools generate" }, "devDependencies": { "@nuxt/devtools": "*", "@nuxt/eslint-config": "^0.3.0", "@nuxtjs/eslint-config-typescript": "^12.3.3", "eslint": "^8.56.0", "nuxt": "^3.11.1", "typescript": "^5.3.3" }, "dependencies": { "@clack/prompts": "^1.1.0", "consola": "^3.4.2", "diff": "^8.0.3", "execa": "^8.0.1", "magicast": "^0.5.2", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "semver": "^7.7.4" }, "bin": { "devtools-wizard": "cli.mjs" } } ``` -------------------------------- ### VueQueryPlugin with Custom Key Suffix Source: https://tanstack.com/query/latest/docs/framework/vue/guides/custom-client.md Demonstrates how the custom query client key is appended internally, simplifying usage for the developer. ```typescript const vueQueryPluginOptions: VueQueryPluginOptions = { queryClientKey: 'Foo', } app.use(VueQueryPlugin, vueQueryPluginOptions) // -> VUE_QUERY_CLIENT:Foo ``` -------------------------------- ### Provide QueryClientConfig to VueQueryPlugin Source: https://tanstack.com/query/latest/docs/framework/vue/guides/custom-client.md Use this when you want VueQueryPlugin to create and manage the QueryClient instance internally. Configure default query options here. ```typescript const vueQueryPluginOptions: VueQueryPluginOptions = { queryClientConfig: { defaultOptions: { queries: { staleTime: 3600 } }, }, } app.use(VueQueryPlugin, vueQueryPluginOptions) ``` -------------------------------- ### Update useQuery and friends signatures to object format Source: https://tanstack.com/query/latest/docs/framework/vue/guides/migrating-to-v5.md In v5, hooks like useQuery, useInfiniteQuery, useMutation, useIsFetching, and useIsMutating now exclusively support a single object signature for their options. This replaces older overloads and simplifies type handling. ```tsx useQuery(key, fn, options) // [!code --] useQuery({ queryKey, queryFn, ...options }) // [!code ++] useInfiniteQuery(key, fn, options) // [!code --] useInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++] useMutation(fn, options) // [!code --] useMutation({ mutationFn, ...options }) // [!code ++] useIsFetching(key, filters) // [!code --] useIsFetching({ queryKey, ...filters }) // [!code ++] useIsMutating(key, filters) // [!code --] useIsMutating({ mutationKey, ...filters }) // [!code ++] ``` -------------------------------- ### Vue App Component with Vue Query Source: https://tanstack.com/query/latest/docs/framework/vue/examples/basic This is the main App.vue component that sets up the application structure, manages post navigation, and includes Vue Query Devtools. It demonstrates how to integrate child components and manage state for visited posts. ```vue ``` -------------------------------- ### Using Fetch with Multiple Cancellable Requests Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-cancellation.md Demonstrates passing an AbortSignal to multiple fetch requests within a single query function. This allows for cancellation of all ongoing requests if the query is cancelled. ```tsx const query = useQuery({ queryKey: ['todos'], queryFn: async ({ signal }) => { const todosResponse = await fetch('/todos', { // Pass the signal to one fetch signal, }) const todos = await todosResponse.json() const todoDetails = todos.map(async ({ details }) => { const response = await fetch(details, { // Or pass it to several signal, }) return response.json() }) return Promise.all(todoDetails) }, }) ``` -------------------------------- ### Nuxt Kit Production Dependencies Source: https://tanstack.com/query/latest/docs/framework/vue/examples/nuxt3 This snippet details the production dependencies for the Nuxt Kit package, including c12, consola, defu, destr, errx, exsolve, ignore, jiti, klona, mlly, ohash, pathe, pkg-types, rc9, scule, semver, tinyglobby, ufo, unctx, and untyped. It specifies Node.js version requirements. ```json { "version": "4.4.7", "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-4.4.7.tgz", "integrity": "sha512-QwtpqNxSOLyJH1UoDpcgsfzVEw95J0893hn1A+CvgeOxoTos1BGvD15D1v/OVQ2MK1EpfnFZJby51t1yudOvBA==", "dev": true, "dependencies": { "c12": "^3.3.4", "consola": "^3.4.2", "defu": "^6.1.7", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.7.0", "klona": "^2.0.6", "mlly": "^1.8.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.1", "rc9": "^3.0.1", "scule": "^1.3.0", "semver": "^7.8.1", "tinyglobby": "^0.2.17", "ufo": "^1.6.4", "unctx": "^2.5.0", "untyped": "^2.0.0" }, "engines": { "node": ">=18.12.0" } } ``` -------------------------------- ### Use Custom QueryClient Key in Query Options Source: https://tanstack.com/query/latest/docs/framework/vue/guides/custom-client.md When using a custom context key, specify it within the query options to ensure the correct QueryClient is used. ```javascript useQuery({ queryKey: ['query1'], queryFn: fetcher, queryClientKey: 'foo', }) ``` -------------------------------- ### Conditionally Fetch Initial Data from Cache Source: https://tanstack.com/query/latest/docs/framework/vue/guides/initial-query-data.md Conditionally provide initial data from the cache based on its freshness. Use `queryClient.getQueryState` to check the `dataUpdatedAt` timestamp and decide if the cached data is recent enough (e.g., not older than 10 seconds). If not, return `undefined` to trigger a fetch. ```tsx const result = useQuery({ queryKey: ['todo', todoId], queryFn: () => fetch(`/todos/${todoId}`), initialData: () => { // Get the query state const state = queryClient.getQueryState(['todos']) // If the query exists and has data that is no older than 10 seconds... if (state && Date.now() - state.dataUpdatedAt <= 10 * 1000) { // return the individual todo return state.data.find((d) => d.id === todoId) } // Otherwise, return undefined and let it fetch from a hard loading state! }, }) ``` -------------------------------- ### Initial Data from a Function Source: https://tanstack.com/query/latest/docs/framework/vue/guides/initial-query-data.md Provide a function to the `initialData` option to execute the data fetching logic only once during query initialization. This is useful for computationally expensive data retrieval. ```tsx const result = useQuery({ queryKey: ['todos'], queryFn: () => fetch('/todos'), initialData: () => getExpensiveTodos(), }) ``` -------------------------------- ### Display Individual Query Background Fetching State in Vue Source: https://tanstack.com/query/latest/docs/framework/vue/guides/background-fetching-indicators.md Use the `isFetching` boolean from `useQuery` to show an indicator when a query is refetching in the background, regardless of its `status`. Ensure `getTodos` is defined elsewhere. ```vue ``` -------------------------------- ### Prefetch an Infinite Query Source: https://tanstack.com/query/latest/docs/framework/vue/guides/prefetching.md Prefetch infinite queries using `prefetchInfiniteQuery`. By default, only the first page is prefetched. Use the `pages` option to prefetch multiple pages and provide `getNextPageParam` to determine subsequent pages. ```tsx const prefetchProjects = async () => { // The results of this query will be cached like a normal query await queryClient.prefetchInfiniteQuery({ queryKey: ['projects'], queryFn: fetchProjects, initialPageParam: 0, getNextPageParam: (lastPage, pages) => lastPage.nextCursor, pages: 3, // prefetch the first 3 pages }) } ``` -------------------------------- ### Mutation Filters Source: https://tanstack.com/query/latest/docs/framework/vue/guides/filters.md Understand how to filter mutations using mutation keys, status, and custom predicates. ```APIDOC ## Mutation Filters A mutation filter is an object with certain conditions to match a mutation with: ```tsx // Get the number of all fetching mutations await queryClient.isMutating() // Filter mutations by mutationKey await queryClient.isMutating({ mutationKey: ['post'] }) // Filter mutations using a predicate function await queryClient.isMutating({ predicate: (mutation) => mutation.state.variables?.id === 1, }) ``` A mutation filter object supports the following properties: - `mutationKey?: MutationKey` - Set this property to define a mutation key to match on. - `exact?: boolean` - If you don't want to search mutations inclusively by mutation key, you can pass the `exact: true` option to return only the mutation with the exact mutation key you have passed. - `status?: MutationStatus` - Allows for filtering mutations according to their status. - `predicate?: (mutation: Mutation) => boolean` - This predicate function will be used as a final filter on all matching mutations. If no other filters are specified, this function will be evaluated against every mutation in the cache. ``` -------------------------------- ### Using queryOptions with select Source: https://tanstack.com/query/latest/docs/framework/vue/guides/query-options.md Demonstrates how type inference works with the select function, ensuring that `query.data` reflects the return type of `select` rather than `queryFn`. This snippet shows a common usage pattern. ```typescript import { useQuery } from '@tanstack/vue-query'; // Assume groupOptions is defined elsewhere and returns queryOptions // const groupOptions = (id: number) => queryOptions({...}) const query = useQuery({ // ...groupOptions(1), select: (data) => data.groupName, }); ``` -------------------------------- ### Global State Before TanStack Query Source: https://tanstack.com/query/latest/docs/framework/vue/guides/does-this-replace-client-state.md Illustrates a typical global state object that includes server-state managed by a client-state library. ```tsx const globalState = { projects, teams, tasks, users, themeMode, sidebarStatus, } ``` -------------------------------- ### Provide a Custom QueryClient Instance to VueQueryPlugin Source: https://tanstack.com/query/latest/docs/framework/vue/guides/custom-client.md Instantiate your QueryClient beforehand and pass it to the VueQueryPlugin. This is useful for integrating with libraries that need access to an already created client. ```typescript const myClient = new QueryClient(queryClientConfig) const vueQueryPluginOptions: VueQueryPluginOptions = { queryClient: myClient, } app.use(VueQueryPlugin, vueQueryPluginOptions) ```