Hooks for managing, caching and syncing asynchronous and remote data in Vue
—
Central management system for all query and mutation operations, providing cache control, data management, and global configuration for TanStack Vue Query.
Main client class for managing queries, mutations, and cache operations.
/**
* Central client for managing all query and mutation operations
* @param config - Optional configuration for cache and default options
*/
class QueryClient {
constructor(config?: QueryClientConfig);
// Query data management
getQueryData<TData>(queryKey: QueryKey): TData | undefined;
setQueryData<TData>(
queryKey: QueryKey,
updater: Updater<TData | undefined, TData | undefined>,
options?: SetDataOptions
): TData | undefined;
getQueriesData<TData>(filters: QueryFilters): Array<[QueryKey, TData | undefined]>;
setQueriesData<TData>(
filters: QueryFilters,
updater: Updater<TData | undefined, TData | undefined>,
options?: SetDataOptions
): Array<[QueryKey, TData | undefined]>;
// Query state management
getQueryState<TData, TError>(queryKey: QueryKey): QueryState<TData, TError> | undefined;
// Cache operations
invalidateQueries(filters?: InvalidateQueryFilters, options?: InvalidateOptions): Promise<void>;
refetchQueries(filters?: RefetchQueryFilters, options?: RefetchOptions): Promise<void>;
cancelQueries(filters?: QueryFilters, options?: CancelOptions): Promise<void>;
removeQueries(filters?: QueryFilters): void;
resetQueries(filters?: QueryFilters, options?: ResetOptions): Promise<void>;
// Query execution
fetchQuery<TData>(options: FetchQueryOptions<TData>): Promise<TData>;
prefetchQuery<TData>(options: FetchQueryOptions<TData>): Promise<void>;
ensureQueryData<TData>(options: EnsureQueryDataOptions<TData>): Promise<TData>;
// Infinite query execution
fetchInfiniteQuery<TData, TPageParam>(
options: FetchInfiniteQueryOptions<TData, TPageParam>
): Promise<InfiniteData<TData, TPageParam>>;
prefetchInfiniteQuery<TData, TPageParam>(
options: FetchInfiniteQueryOptions<TData, TPageParam>
): Promise<void>;
// Status tracking
isFetching(filters?: QueryFilters): number;
isMutating(filters?: MutationFilters): number;
// Default options
setDefaultOptions(options: DefaultOptions): void;
getDefaultOptions(): DefaultOptions | undefined;
setQueryDefaults(queryKey: QueryKey, options: QueryObserverOptions): void;
getQueryDefaults(queryKey: QueryKey): QueryObserverOptions | undefined;
setMutationDefaults(mutationKey: MutationKey, options: MutationObserverOptions): void;
getMutationDefaults(mutationKey: MutationKey): MutationObserverOptions | undefined;
// Cache access
getQueryCache(): QueryCache;
getMutationCache(): MutationCache;
// Lifecycle
mount(): void;
unmount(): void;
clear(): void;
}
interface QueryClientConfig {
queryCache?: QueryCache;
mutationCache?: MutationCache;
defaultOptions?: DefaultOptions;
}
interface DefaultOptions {
queries?: QueryObserverOptions & ShallowOption;
mutations?: MutationObserverOptions & ShallowOption;
hydrate?: HydrateOptions['defaultOptions'];
dehydrate?: DehydrateOptions;
}Usage Examples:
import { QueryClient } from '@tanstack/vue-query';
// Basic client setup
const queryClient = new QueryClient();
// Client with custom configuration
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
gcTime: 1000 * 60 * 30, // 30 minutes
retry: 3,
refetchOnWindowFocus: false,
},
mutations: {
retry: 1,
},
},
});
// Data management
const userData = queryClient.getQueryData(['user', userId]);
queryClient.setQueryData(['user', userId], (oldData) => ({
...oldData,
lastSeen: new Date().toISOString()
}));
// Cache operations
await queryClient.invalidateQueries({ queryKey: ['posts'] });
await queryClient.refetchQueries({ queryKey: ['user'] });
queryClient.removeQueries({ queryKey: ['temp'] });
// Prefetching
await queryClient.prefetchQuery({
queryKey: ['posts', 'popular'],
queryFn: () => fetch('/api/posts/popular').then(res => res.json()),
staleTime: 1000 * 60 * 10,
});
// Ensure data exists
const userData = await queryClient.ensureQueryData({
queryKey: ['user', userId],
queryFn: () => fetch(`/api/users/${userId}`).then(res => res.json()),
});
// Status checking
const fetchingCount = queryClient.isFetching();
const mutatingCount = queryClient.isMutating();Composable to access the QueryClient instance within Vue components.
/**
* Access the QueryClient instance via Vue's injection system
* @param id - Optional client ID for multi-client setups
* @returns QueryClient instance
* @throws Error if called outside setup() or no client found
*/
function useQueryClient(id?: string): QueryClient;Usage Examples:
import { useQueryClient } from '@tanstack/vue-query';
export default {
setup() {
const queryClient = useQueryClient();
const invalidateUserData = () => {
queryClient.invalidateQueries({ queryKey: ['user'] });
};
const prefetchUserPosts = async (userId) => {
await queryClient.prefetchQuery({
queryKey: ['posts', 'user', userId],
queryFn: () => fetch(`/api/users/${userId}/posts`).then(res => res.json())
});
};
return {
invalidateUserData,
prefetchUserPosts
};
}
};Cache classes for advanced cache management and event handling.
/**
* Cache for storing and managing query data
*/
class QueryCache {
constructor(config?: QueryCacheConfig);
find<TData, TError>(filters: QueryFilters): Query<TData, TError> | undefined;
findAll(filters?: QueryFilters): Array<Query>;
subscribe(listener: QueryCacheNotifyEventListener): () => void;
clear(): void;
}
/**
* Cache for storing and managing mutation data
*/
class MutationCache {
constructor(config?: MutationCacheConfig);
find<TData, TError, TVariables, TContext>(
filters: MutationFilters
): Mutation<TData, TError, TVariables, TContext> | undefined;
findAll(filters?: MutationFilters): Array<Mutation>;
subscribe(listener: MutationCacheNotifyEventListener): () => void;
clear(): void;
}
interface QueryCacheConfig {
onError?: (error: unknown, query: Query<unknown, unknown>) => void;
onSuccess?: (data: unknown, query: Query<unknown, unknown>) => void;
onSettled?: (data: unknown | undefined, error: unknown | null, query: Query<unknown, unknown>) => void;
}
interface MutationCacheConfig {
onError?: (error: unknown, variables: unknown, context: unknown, mutation: Mutation<unknown, unknown, unknown, unknown>) => void;
onSuccess?: (data: unknown, variables: unknown, context: unknown, mutation: Mutation<unknown, unknown, unknown, unknown>) => void;
onSettled?: (data: unknown | undefined, error: unknown | null, variables: unknown, context: unknown, mutation: Mutation<unknown, unknown, unknown, unknown>) => void;
}Usage Examples:
import { QueryCache, MutationCache } from '@tanstack/vue-query';
// Custom cache with global error handling
const queryCache = new QueryCache({
onError: (error, query) => {
console.error('Query error:', error, 'Query key:', query.queryKey);
if (error.status === 401) {
// Handle authentication errors globally
router.push('/login');
}
}
});
const mutationCache = new MutationCache({
onError: (error) => {
console.error('Mutation error:', error);
// Show global error notification
showErrorToast(error.message);
}
});
const queryClient = new QueryClient({
queryCache,
mutationCache
});
// Subscribe to cache events
const unsubscribe = queryCache.subscribe((event) => {
if (event.type === 'added') {
console.log('Query added:', event.query.queryKey);
}
});
// Cleanup
onUnmounted(() => {
unsubscribe();
});// Core data types
type QueryKey = ReadonlyArray<unknown>;
type MutationKey = ReadonlyArray<unknown>;
// Updater function type
type Updater<TInput, TOutput> = TOutput | ((input: TInput) => TOutput);
// Query state interface
interface QueryState<TData = unknown, TError = DefaultError> {
data: TData | undefined;
dataUpdateCount: number;
dataUpdatedAt: number;
error: TError | null;
errorUpdateCount: number;
errorUpdatedAt: number;
fetchFailureCount: number;
fetchFailureReason: TError | null;
fetchMeta: FetchMeta | null;
isInvalidated: boolean;
status: QueryStatus;
fetchStatus: FetchStatus;
}
// Filter types
interface QueryFilters<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> {
exact?: boolean;
fetchStatus?: FetchStatus;
predicate?: (query: Query<TQueryFnData, TError, TData, TQueryKey>) => boolean;
queryKey?: TQueryKey;
stale?: boolean;
status?: QueryStatus;
type?: QueryTypeFilter;
}
interface MutationFilters {
exact?: boolean;
fetching?: boolean;
mutationKey?: MutationKey;
predicate?: (mutation: Mutation<any, any, any, any>) => boolean;
status?: MutationStatus;
}
// Options interfaces
interface SetDataOptions {
updatedAt?: number;
}
interface InvalidateOptions {
cancelRefetch?: boolean;
}
interface RefetchOptions {
cancelRefetch?: boolean;
}
interface CancelOptions {
revert?: boolean;
silent?: boolean;
}
interface ResetOptions {
cancelRefetch?: boolean;
}
// Fetch options
interface FetchQueryOptions<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> {
queryKey: TQueryKey;
queryFn?: QueryFunction<TQueryFnData, TQueryKey>;
staleTime?: number;
gcTime?: number;
retry?: boolean | number | ((failureCount: number, error: TError) => boolean);
retryDelay?: number | ((retryAttempt: number, error: TError) => number);
signal?: AbortSignal;
meta?: QueryMeta;
}
interface EnsureQueryDataOptions<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>
extends FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey> {
revalidateIfStale?: boolean;
}
// Event listener types
type QueryCacheNotifyEventListener = (event: QueryCacheNotifyEvent) => void;
type MutationCacheNotifyEventListener = (event: MutationCacheNotifyEvent) => void;
interface QueryCacheNotifyEvent {
type: 'added' | 'removed' | 'updated';
query: Query<any, any, any, any>;
}
interface MutationCacheNotifyEvent {
type: 'added' | 'removed' | 'updated';
mutation: Mutation<any, any, any, any>;
}Install with Tessl CLI
npx tessl i tessl/npm-tanstack--vue-query