@vueuse/shared 15.0.0
Framework-agnostic reactive utilities for Vue. Peer dependency vue ^3.5.0
(package.json:40). ESM-only: "type": "module" and no CJS build in dist
(package.json:2). Requires Node.js >= 22 (package.json:37).
Source citations like dist/index.js:904 refer to the prepared package source.
Function docs: https://vueuse.org/<functionName>.
Critical v15 rules
useThrottleFndefaulttrailingchanged fromfalsetotruein v15.0.0. Defaults are nowms = 200, trailing = true, leading = true, rejectOnCancel = false(dist/index.js:904). Release: https://github.com/vueuse/vueuse/releases/tag/v15.0.0 To get v14 leading-edge-only behavior, passtrailing = falseexplicitly.computedEager/eagerComputedare deprecated and slated for removal. Use Vue 3.4+computedinstead (dist/index.d.ts:5-18).watchPausable/pausableWatchare deprecated on every overload. Use Vue's built-inwatch, whose handle already haspause()andresume()(dist/index.js:1021, dist/index.d.ts:1459-1466).- Prefer primary names over deprecated aliases; see the table in migration-v15.
- Timer composables are no-ops on the server:
useIntervalFnanduseTimeoutFnonly start timers whenisClient(dist/index.js:1654, dist/index.js:1726-1729).
Common tasks
import { useDebounceFn, useThrottleFn } from '@vueuse/shared'
// Debounced fn: returns a promise; cancel/flush/isPending attached
const search = useDebounceFn(query => fetchApi(query), 300, { maxWait: 1000 })
// Rate-limit scroll/resize; v15 fires on BOTH edges by default
const onScroll = useThrottleFn(handler, 200) // leading + trailing
const onScrollV14 = useThrottleFn(handler, 200, false) // trailing=false, v14 style
import { until, whenever } from '@vueuse/shared'
// One-shot async flow control instead of manual watchers
await until(isReady).toBe(true, { timeout: 5000, throwOnTimeout: true })
// Runs only while truthy; { once: true } auto-stops after the first run
whenever(isReady, data => render(data), { once: true })
import { createInjectionState } from '@vueuse/shared'
// Typed provide/inject pair without manual InjectionKey
const [useProvideStore, useStore] = createInjectionState(() => {
const count = ref(0)
return { count, inc: () => count.value++ }
}, { defaultValue: { count: ref(0), inc: () => {} } })
import { refManualReset, syncRef } from '@vueuse/shared'
const message = refManualReset('idle') // message.reset() restores 'idle'
const num = ref(10), str = ref('10')
syncRef(num, str, { // transform is required when
transform: { // types differ (type-level check)
ltr: v => String(v),
rtl: v => Number(v),
},
})
More worked patterns: reactivity-utilities, watch-utilities.
Choosing state-sharing tools
| Tool | Lifetime | Use when |
|---|---|---|
createGlobalState | App lifetime, never disposed (dist/index.js:169-180) | App-wide singleton state |
createSharedComposable | Disposed when last subscriber leaves (dist/index.js:583-605) | One shared instance of a composable, e.g. one useMouse |
createInjectionState | Tied to component tree | Typed provider/consumer stores |
provideLocal / injectLocal | Same component or scope | Provide and inject within one component |
SSR: createSharedComposable falls back to the plain composable on the server,
so every request gets fresh state (dist/index.js:584). Details:
state-sharing.
References
- api-surface: complete export inventory with signatures and defaults
- migration-v15: v14 to v15 changes and deprecated alias map
- debounce-throttle: filters,
useDebounceFn,useThrottleFnsemantics - watch-utilities: watch variants,
until,whenever - reactivity-utilities: ref/computed/sync helpers
- state-sharing: global, shared, and injected state
- timers-and-utils: timers, counters, formatting, plain utils