How to destructure reactive objects safely in Vue 3?
Jun 28, 2025 am 12:44 AMTo safely destructure reactive objects in Vue 3 while preserving reactivity, use toRefs() with reactive() or prefer ref(). 1. When using reactive(), always wrap the object with toRefs() before destructuring to ensure each property remains a ref and stays reactive. 2. Alternatively, use ref() for individual values, which inherently preserves reactivity without needing additional wrappers. 3. For nested structures, avoid deep destructuring as toRefs() does not handle recursion; instead, access nested properties via their full path or restructure data to keep reactivity. 4. When using defineProps() inside <script setup>, assign props to a variable first before destructuring to maintain reactivity.
When working with reactive objects in Vue 3, especially using reactive()
or ref()
, destructuring can easily break reactivity if not handled correctly. The main issue is that when you destructure a reactive object, the resulting variables lose their connection to the original reactive source. So, to safely destructure reactive values, you need to either use toRefs()
or stick with ref()
-based state.
Use toRefs()
when destructuring reactive()
objects
If you're using reactive()
to create an object and want to destructure it without losing reactivity, wrap it with toRefs()
. This ensures each property becomes a ref
and retains its reactivity:
const state = reactive({ count: 0, name: 'Vue' }); const { count, name } = toRefs(state);
Now, count
and name
are refs, and you can safely use them in your template or logic while keeping them reactive. If you skip toRefs()
, like this:
const { count } = reactive({ count: 0 });
Then count
becomes a plain number — not reactive anymore. That’s a common gotcha.
So whenever you destructure a reactive()
object, always remember to pass it through toRefs()
unless you’re only using the whole object later.
Prefer ref()
for individual values
Another approach is to avoid reactive()
altogether and use ref()
for individual values. This keeps things simple and avoids issues with destructuring:
const count = ref(0); const name = ref('Vue');
These are already refs, so you can use them directly anywhere — templates, computed properties, watchers — and they stay reactive no matter how you access them.
This pattern works especially well when you have unrelated pieces of state. It also plays nicely with TypeScript and makes it easier to extract logic into custom composables.
Watch out for nested structures
If your reactive object has nested properties, toRefs()
won’t help with deep nesting. For example:
const state = reactive({ user: { name: 'Alice', age: 25 } });
If you do:
const { user } = state;
Then user
remains reactive because it's part of the proxy chain. But if you go further:
const { name } = state.user;
Then name
is just a string and not reactive. To handle this, you could make user
a ref
by restructuring your data model, or keep using state.user.name
directly in your templates.
In short:
- Keep using the full path (
state.user.name
) to preserve reactivity - Or restructure your data to avoid deep destructuring
- Don't expect
toRefs()
to work recursively on nested objects
Bonus tip: Destructure with setup()
and defineProps()
If you're working inside a <script setup>
block and destructuring props, always use defineProps()
properly. Don’t do this:
const { foo } = defineProps(['foo']); // ? Not safe
Instead, define props as an object and destructure normally:
const props = defineProps({ foo: String }); const { foo } = props; // ? Safe to use
Because Vue automatically wraps props in a shallow ref, even after destructuring, you still get reactivity. But this only works if you first assign props
and then destructure from it.
That’s basically it. Destructuring reactive objects isn’t hard, but it does require knowing which patterns keep things reactive and which ones don’t. Stick with toRefs()
for reactive()
or prefer ref()
for simplicity, and watch out for edge cases like nested structures and props.
The above is the detailed content of How to destructure reactive objects safely in Vue 3?. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

SuspenseinVue3simplifieshandlingasynccomponentsbymanagingloadingstatesandintegratingerrorhandling.1.Itwrapsasynccontentanddisplaysfallbackcontentlikespinnersuntilthecomponentloads.2.YoudefineasynccomponentsusingdefineAsyncComponentandwraptheminaSuspe

Vue3’sCompositionAPIimprovescomponentdevelopmentbyofferingamoreflexibleandintuitiveapproachcomparedtotheOptionsAPI.1.Itallowsmorenaturalcodeorganizationbygroupingrelatedlogictogetherinsteadofsplittingacrossdata,methods,computed,andwatch.2.Itenablesre

Migrating to Vue3 requires starting from four aspects: compatibility checking, responsive system changes, component communication adjustment, and building tool upgrade. First, check whether the project dependencies support Vue3, especially core libraries such as Vuex and VueRouter, and consider using @vue/compat for gradual migration; second, the responsive system is implemented by Proxy, and ref/reactive needs to explicitly declare responsive data, replacing Vue.set; third, the life cycle hook is changed to onBeforeMount, onMounted, etc., and it is necessary to explicitly import and declare props/emits; fourth, if TypeScript is used, the configuration file and toolchain support need to be updated. It is recommended to complete it first.

Vue3 has improved in many key aspects compared to Vue2. 1.Composition API provides a more flexible logical organization method, allowing centralized management of related logic, while still supporting Vue2's Options API; 2. Better performance and smaller package size, the core library is reduced by about 30%, the rendering speed is faster and supports better tree shake optimization; 3. The responsive system uses ES6Proxy to solve the problem of unable to automatically track attribute addition and deletion in Vue2, making the responsive mechanism more natural and consistent; 4. Built-in better support for TypeScript, support multiple node fragments and custom renderer API, improving flexibility and future adaptability. Overall, Vue3 is a smooth upgrade to Vue2,

TypeScriptenhancesVue3projectswithtypesafetyandimprovedtooling,especiallywhenusingtheCompositionAPI.TosetupVue3withTypeScript,useViteorVueCLI,installrequiredpackages,createatsconfig.jsonfile,andrename.jsfilesto.ts.WhenusingtheCompositionAPI,definepro

ThemaindifferencebetweenVue3’sOptionsAPIandCompositionAPIliesincodeorganizationandlogicreuse.TheOptionsAPIgroupscodebypredefinedoptionslikedata,methods,andcomputed,makingitpredictablebutpotentiallymessyinlargecomponents.Incontrast,theCompositionAPIor

TosafelydestructurereactiveobjectsinVue3whilepreservingreactivity,usetoRefs()withreactive()orpreferref().1.Whenusingreactive(),alwayswraptheobjectwithtoRefs()beforedestructuringtoensureeachpropertyremainsarefandstaysreactive.2.Alternatively,useref()f

In Vue3, multiple v-model bindings cannot be used directly on a component, but similar functions can be achieved through custom model properties and events. 1. Use the model option to customize the prop and event name, for example, implement multiple v-model-like bindings through model:{prop:'title', event:'update:title'}; 2. Manually pass props and trigger events, such as binding: username and @update:username in parent component, declare emit in child component; 3. Use defineProps and defineEmits in CompositionAPI
