Vue 11: ref vs reactive
easy⏱ 5 mincoursevue
ref() needs .value, reactive() doesn't
ref(value) returns an object with a single .value property — read/write it explicitly in JavaScript (count.value++), but Vue templates automatically unwrap top-level refs, so {{ count }} just works. reactive(obj) instead returns a Proxy over the object itself — access and mutate its properties directly (user.name = 'X'), no .value ever, in JS OR the template. Use ref for primitives (numbers, strings, booleans) and reactive for objects/arrays you'll keep intact and mutate in place.
import { ref, reactive } from 'vue';
const count = ref(0);
count.value++; // must use .value in JS
const user = reactive({ name: 'Ada' });
user.name = 'Grace'; // direct mutation, no .value
// In a template, Vue auto-unwraps top-level refs:
// {{ count }} -- correct
// {{ count.value }} -- wrong, unnecessary in templates
Destructuring reactive() breaks reactivity
A common pitfall: destructuring a reactive() object — const { name } = user — breaks reactivity, because you copy out the current primitive value, not a live binding. Vue provides toRefs(user) to destructure into individual refs that stay connected to the source. ref() doesn't have this problem since you always interact through the .value box, which IS the reactive connection.
Build the ProfileCard
Click ref++ and confirm the counter uses .value inside increment(). Click promote (reactive) and confirm user.role is mutated with no .value at all — yet both changes show up in the template immediately.