Both create reactive state in the Composition API, but they work differently. ref wraps any value (including primitives) in a reactive container; reactive makes an object deeply reactive directly.
Both create reactive state in the Composition API, but they work differently. ref wraps any value (including primitives) in a reactive container; reactive makes an object deeply reactive directly.
<script setup>
import { ref } from "vue";
const count = ref(0); // wraps a primitive
const user = ref({ name: "Ann" });
function inc() {
count.value++; // ⚠️ in SCRIPT you must use .value
user.value.name = "Bob";
}
</script>
<template>
<p>{{ count }}</p> <!-- ✅ in TEMPLATE, .value is auto-unwrapped -->
</template>
The key quirk: in JavaScript you access a ref through .value; in the template Vue unwraps it automatically. Forgetting .value in script is the most common beginner bug.
<script setup>
import { reactive } from "vue";
const state = reactive({ count: 0, user: { name: "Ann" } });
state.count++; // ✅ access directly, no .value
state.user.name = "Bob"; // deeply reactive
</script>
reactive only works on objects/arrays (not primitives) and you use the properties directly.
let state = reactive({ count: 0 });
state = { count: 5 }; // ❌ breaks reactivity (lost the reactive proxy)
const { count } = state; // ❌ destructuring loses reactivity
Reassigning a reactive object or destructuring its properties disconnects them from reactivity — a frequent gotcha. ref doesn't have this problem (you reassign .value).
ref → primitives, and the recommended default (works for everything, easy to reassign)
reactive→ when you want a grouped object of state without .value (but mind destructuring)
Many teams standardize on ref everywhere for consistency.
ref અને reactive Vue 3 ના Composition API સ્ટેટનો ভিત્તિ છે.
સમજવું કે ref ને સ્ક્રિપ્ટમાં .value ની જરૂર છે (templates માં auto-unwrapped) અને reactive પુનઃસોંપણ/destructuring પર તેની reactivity ગુમાવે છે તે Vue માં બે સૌથી સામાન્ય reactivity bugs ને રોકે છે.