Does destructuring a Vue 3 reactive() object in setup() break template reactivity?
0 reputation · 05 Aug 2026, 07:52 UTC
0 reputation · 05 Aug 2026, 07:52 UTC
Goal: Bind template properties to destructured state from a `reactive()` object inside `setup()` while preserving reactivity.
Constraint: `reactive()` wraps an object in a Proxy, but destructuring extracts plain values and severs the reactivity link, so later mutations may not update templates bound to those locals. `ref()` keeps the container reactive, and `toRefs()` converts the object into linked refs, though replacing the entire source object does not update refs created from the previous object.
Assumption: Vue 3.2 or later using the Composition API; Vue 2 or earlier Vue 3 minor releases may behave differently. Confirm the installed version before applying these patterns.
Does destructuring a `reactive()` object in `setup()` always sever reactivity for template-bound variables? Is `toRefs()` appropriate when the source object might be replaced entirely? Which pattern—`ref()`, direct `reactive()` property access, or `toRefs()`—best preserves reactivity for destructured scalar state?
34775 reputation · 05 Aug 2026, 14:35 UTC
Yes. Destructuring a reactive() object inside setup() extracts plain JavaScript values at that moment, severing the Proxy linkage. Template bindings to those local variables will not update when the source reactive state mutates.
reactive() wraps an object in a Vue Proxy that intercepts property access. Destructuring (const { count } = state) reads the property once and assigns the raw value to a new variable. That variable is no longer connected to the Proxy, so subsequent mutations to state.count never reach the template.
toRefs() — Converts each property of a reactive object into a ref that still proxies the original object. const { count } = toRefs(state) gives you a reactive count ref. In templates, refs unwrap automatically; in script, use count.value.state.count in the template remains fully reactive without any wrapping. This is the simplest approach when you don't need destructured locals.ref() for individual values — Wrap scalars explicitly: const count = ref(0). Requires .value in script but works reliably.If you ever reassign the entire reactive object (state = reactive(newObject)), any refs created by toRefs(state) become stale — they still point to the old object. After a full replacement, you must call toRefs() again on the new object.
toRefs() — provided the reactive object is never replaced.toRefs() after each replacement.state.prop directly in the template.Does your component ever replace the entire reactive object (e.g., state = reactive({...})) after initial setup, or does it only mutate properties in place? This determines whether toRefs() is safe to use without re-application.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.