Skip to main content
Practice Problems

Ref vs reactive in Vue.js

ref vs reactive

Vue 3 Composition API provides two main ways to create reactive state: ref and reactive. Understanding their differences is essential for writing correct Vue code.


ref

ref wraps a value in a reactive object with a .value property:

vue
<script setup> import { ref } from 'vue' const count = ref(0) const name = ref('Alice') const user = ref({ name: 'Alice', age: 25 }) // Access/mutate via .value in script count.value++ name.value = 'Bob' user.value.age = 26 // Can reassign the whole value user.value = { name: 'Charlie', age: 30 } </script> <template> <!-- .value is automatically unwrapped in templates --> <p>{{ count }}</p> <p>{{ name }}</p> </template>

reactive

reactive creates a deeply reactive proxy of an object:

vue
<script setup> import { reactive } from 'vue' const state = reactive({ count: 0, user: { name: 'Alice', age: 25 }, items: ['a', 'b', 'c'] }) // Access directly β€” no .value needed state.count++ state.user.name = 'Bob' state.items.push('d') // ❌ Cannot reassign the whole object! // state = { count: 1 } // This breaks reactivity! </script> <template> <p>{{ state.count }}</p> <p>{{ state.user.name }}</p> </template>

Key Differences

Featurerefreactive
Works withAny type (primitives + objects)Objects only (no primitives)
Access in script.value requiredDirect access
Access in templateAuto-unwrappedDirect access
Reassignmentβœ… Can reassign .value❌ Cannot reassign whole object
Destructuringβœ… Works (keeps reactivity)❌ Loses reactivity
TypeScriptRef<T> typeOriginal type

The Destructuring Problem

vue
<script setup> import { reactive, toRefs } from 'vue' const state = reactive({ name: 'Alice', age: 25 }) // ❌ Destructuring loses reactivity! let { name, age } = state name = 'Bob' // NOT reactive β€” won't update the template // βœ… Use toRefs to keep reactivity const { name: nameRef, age: ageRef } = toRefs(state) nameRef.value = 'Bob' // βœ… Reactive! </script>

When to Use Which

Primitive value (string, number, boolean)? β†’ ref Want to replace the entire value? β†’ ref Object/array you only mutate properties of? β†’ reactive (or ref β€” both work) Simple component state? β†’ ref (most common, recommended by Vue team)

Common Pattern: ref for Everything

The Vue team recommends using ref as the default:

vue
<script setup> import { ref } from 'vue' // βœ… Consistent β€” always use ref const count = ref(0) const name = ref('Alice') const users = ref([{ name: 'Alice' }, { name: 'Bob' }]) const form = ref({ email: '', password: '' }) </script>

Important:

ref works with any type and requires .value in script. reactive works only with objects and provides direct access. The Vue team recommends ref as the default because it's more flexible (supports primitives, allows reassignment). Use reactive when you prefer dot-notation for complex state objects.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems