Collection of essential Vue Composition Utilities providing 146+ reactive composable functions for Vue 3 applications
—
Core reactive state utilities for managing component and application state with persistence, history tracking, and v-model integration.
Reactive LocalStorage/SessionStorage with automatic serialization and type safety.
/**
* Reactive storage utility with automatic serialization
* @param key - Storage key
* @param defaults - Default value
* @param storage - Storage instance (localStorage by default)
* @param options - Configuration options
* @returns Reactive ref with storage sync
*/
function useStorage<T>(
key: string,
defaults: MaybeRefOrGetter<T>,
storage?: StorageLike,
options?: UseStorageOptions<T>
): RemovableRef<T>;
interface UseStorageOptions<T> {
flush?: 'pre' | 'post' | 'sync';
deep?: boolean;
listenToStorageChanges?: boolean;
writeDefaults?: boolean;
mergeDefaults?: boolean | ((storageValue: T, defaults: T) => T);
serializer?: StorageSerializer<T>;
onError?: (error: Error) => void;
shallow?: boolean;
initOnMounted?: boolean;
}
interface RemovableRef<T> extends Ref<T> {
/** Remove the storage item and reset to default */
remove(): void;
}
interface StorageSerializer<T> {
read(value: string): T;
write(value: T): string;
}Usage Examples:
import { useStorage } from "@vueuse/core";
// String storage
const name = useStorage('user-name', 'Anonymous');
// Object storage with automatic JSON serialization
const settings = useStorage('app-settings', {
theme: 'light',
language: 'en'
});
// Array storage
const favorites = useStorage('favorites', [] as string[]);
// Custom serializer for dates
const lastLogin = useStorage('last-login', new Date(), undefined, {
serializer: {
read: (v: string) => new Date(v),
write: (v: Date) => v.toISOString()
}
});
// Remove storage item
settings.remove(); // Resets to default and removes from storageShorthand for useStorage with localStorage.
/**
* Reactive localStorage wrapper
* @param key - Storage key
* @param defaults - Default value
* @param options - Configuration options
* @returns Reactive ref synced with localStorage
*/
function useLocalStorage<T>(
key: string,
defaults: MaybeRefOrGetter<T>,
options?: UseStorageOptions<T>
): RemovableRef<T>;Shorthand for useStorage with sessionStorage.
/**
* Reactive sessionStorage wrapper
* @param key - Storage key
* @param defaults - Default value
* @param options - Configuration options
* @returns Reactive ref synced with sessionStorage
*/
function useSessionStorage<T>(
key: string,
defaults: MaybeRefOrGetter<T>,
options?: UseStorageOptions<T>
): RemovableRef<T>;Reactive async storage for custom storage backends.
/**
* Reactive async storage utility
* @param key - Storage key
* @param defaults - Default value
* @param storage - Async storage instance
* @param options - Configuration options
* @returns Reactive ref with async storage sync
*/
function useStorageAsync<T>(
key: string,
defaults: MaybeRefOrGetter<T>,
storage: StorageLikeAsync,
options?: UseStorageAsyncOptions<T>
): RemovableRef<T>;
interface StorageLikeAsync {
getItem: (key: string) => Awaitable<string | null>;
setItem: (key: string, value: string) => Awaitable<void>;
removeItem: (key: string) => Awaitable<void>;
}Shorthand for props + emit -> ref pattern in Vue components.
/**
* Shorthand for v-model binding in components
* @param props - Component props object
* @param key - Prop key to bind (defaults to 'modelValue')
* @param emit - Component emit function
* @param options - Configuration options
* @returns Writable computed ref
*/
function useVModel<P extends object, K extends keyof P>(
props: P,
key?: K,
emit?: (name: string, ...args: any[]) => void,
options?: UseVModelOptions<P[K], true>
): WritableComputedRef<P[K]>;
interface UseVModelOptions<T, Passive> {
passive?: Passive;
eventName?: string;
deep?: boolean;
defaultValue?: T;
clone?: boolean | CloneFn<T>;
shouldEmit?: (v: T) => boolean;
}Usage Examples:
import { useVModel } from "@vueuse/core";
// In a component with v-model
export default defineComponent({
props: {
modelValue: String,
count: Number
},
emits: ['update:modelValue', 'update:count'],
setup(props, { emit }) {
// Default v-model binding
const value = useVModel(props, 'modelValue', emit);
// Named v-model binding
const count = useVModel(props, 'count', emit);
// Passive mode (no emit, only reactive to prop changes)
const readOnly = useVModel(props, 'modelValue', emit, { passive: true });
return { value, count, readOnly };
}
});Shorthand for multiple v-model bindings.
/**
* Multiple v-model bindings shorthand
* @param props - Component props object
* @param emit - Component emit function
* @param options - Configuration options
* @returns Object with reactive refs for each prop
*/
function useVModels<P extends object>(
props: P,
emit?: (name: string, ...args: any[]) => void,
options?: UseVModelsOptions
): ToRefs<P>;
interface UseVModelsOptions {
deep?: boolean;
passive?: boolean;
}Track changes to a ref with undo/redo capabilities.
/**
* Track ref value history with undo/redo
* @param source - Source ref to track
* @param options - Configuration options
* @returns History utilities
*/
function useRefHistory<Raw, Serialized = Raw>(
source: Ref<Raw>,
options?: UseRefHistoryOptions<Raw, Serialized>
): UseRefHistoryReturn<Raw, Serialized>;
interface UseRefHistoryReturn<Raw, Serialized> {
source: Ref<Raw>;
history: Ref<UseRefHistoryRecord<Serialized>[]>;
last: Ref<UseRefHistoryRecord<Serialized>>;
undoStack: Ref<UseRefHistoryRecord<Serialized>[]>;
redoStack: Ref<UseRefHistoryRecord<Serialized>[]>;
canUndo: Ref<boolean>;
canRedo: Ref<boolean>;
undo(): void;
redo(): void;
clear(): void;
pause(): void;
resume(): void;
commit(): void;
}
interface UseRefHistoryRecord<T> {
snapshot: T;
timestamp: number;
}Usage Examples:
import { ref } from "vue";
import { useRefHistory } from "@vueuse/core";
const counter = ref(0);
const { history, undo, redo, canUndo, canRedo } = useRefHistory(counter);
counter.value = 1;
counter.value = 2;
counter.value = 3;
console.log(history.value.length); // 4 (including initial)
console.log(canUndo.value); // true
undo(); // counter.value becomes 2
undo(); // counter.value becomes 1
console.log(canRedo.value); // true
redo(); // counter.value becomes 2Manual ref history tracking (no automatic commits).
/**
* Manual ref history tracking without automatic commits
* @param source - Source ref to track
* @param options - Configuration options
* @returns History utilities with manual commit
*/
function useManualRefHistory<Raw, Serialized = Raw>(
source: Ref<Raw>,
options?: UseManualRefHistoryOptions<Raw, Serialized>
): UseManualRefHistoryReturn<Raw, Serialized>;Debounced ref history tracking.
/**
* Debounced ref history tracking
* @param source - Source ref to track
* @param options - Configuration options including debounce timing
* @returns History utilities with debounced commits
*/
function useDebouncedRefHistory<Raw, Serialized = Raw>(
source: Ref<Raw>,
options?: UseDebouncedRefHistoryOptions<Raw, Serialized>
): UseRefHistoryReturn<Raw, Serialized>;
interface UseDebouncedRefHistoryOptions<Raw, Serialized> extends UseRefHistoryOptions<Raw, Serialized> {
debounce?: number;
}Throttled ref history tracking.
/**
* Throttled ref history tracking
* @param source - Source ref to track
* @param options - Configuration options including throttle timing
* @returns History utilities with throttled commits
*/
function useThrottledRefHistory<Raw, Serialized = Raw>(
source: Ref<Raw>,
options?: UseThrottledRefHistoryOptions<Raw, Serialized>
): UseRefHistoryReturn<Raw, Serialized>;
interface UseThrottledRefHistoryOptions<Raw, Serialized> extends UseRefHistoryOptions<Raw, Serialized> {
throttle?: number;
}Reactive async state management with loading states.
/**
* Reactive async state management
* @param promise - Promise or function returning promise
* @param initialState - Initial state value
* @param options - Configuration options
* @returns Async state utilities
*/
function useAsyncState<Data, Params extends any[] = [], Shallow extends boolean = true>(
promise: Promise<Data> | ((...args: Params) => Promise<Data>),
initialState: MaybeRef<Data>,
options?: UseAsyncStateOptions<Shallow, Data>
): UseAsyncStateReturn<Data, Params, Shallow>;
interface UseAsyncStateReturn<Data, Params extends any[], Shallow extends boolean> {
state: ShallowUnwrapRef<Ref<Data>>;
isReady: Ref<boolean>;
isLoading: Ref<boolean>;
error: Ref<unknown>;
execute: (...args: Params) => Promise<Data>;
executeImmediate: (...args: Params) => Promise<Data>;
}Usage Examples:
import { useAsyncState } from "@vueuse/core";
// With promise
const { state, isReady, isLoading, error } = useAsyncState(
fetch('/api/user').then(r => r.json()),
{}
);
// With function
const { state, execute, isLoading } = useAsyncState(
async (id: string) => {
const response = await fetch(`/api/user/${id}`);
return response.json();
},
null,
{ immediate: false }
);
// Execute manually
await execute('123');Create an asynchronous computed dependency.
/**
* Create an asynchronous computed dependency
* @param evaluationCallback - Async evaluation function
* @param initialState - Initial state
* @param options - Configuration options
* @returns Async computed ref
*/
function computedAsync<T>(
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
initialState?: T,
options?: AsyncComputedOptions
): ComputedRef<T> | Ref<T>;
interface AsyncComputedOptions {
lazy?: boolean;
evaluating?: Ref<boolean>;
shallow?: boolean;
flush?: 'pre' | 'post' | 'sync';
onError?: (error: unknown) => void;
}
type AsyncComputedOnCancel = (fn: () => void) => void;Combine computed and inject functionality.
/**
* Combine computed and inject
* @param key - Injection key
* @param fn - Computed function
* @param defaultSource - Default value source
* @param treatDefaultAsFactory - Treat default as factory function
* @returns Computed ref with injected dependency
*/
function computedInject<T, K>(
key: InjectionKey<T> | string,
fn: (source: T) => K,
defaultSource?: T | (() => T),
treatDefaultAsFactory?: boolean
): ComputedRef<K>;Install with Tessl CLI
npx tessl i tessl/npm-vueuse--core