Lessons in this course (17)

5. ref, reactive, computed and watch

Basic★ Must knowLesson 5 of 17
ts
import { ref, reactive, computed, watch, watchEffect } from "vue";

const count = ref(0);                         // any value; access .value in script, auto-unwrapped in templates
count.value++;

const cart = reactive({ items: [] as Item[], coupon: "" });   // objects only; deep reactive Proxy
cart.items.push({ id: 1, price: 900, qty: 2 });

const total = computed(() => cart.items.reduce((s, i) => s + i.price * i.qty, 0));   // cached until deps change

watch(count, (newVal, oldVal) => console.log(`count ${oldVal} → ${newVal}`));         // specific source, lazy
watch(() => cart.coupon, async code => { cart.discount = await validateCoupon(code); });
watch(() => props.userId, id => loadUser(id), { immediate: true });
watchEffect(() => console.log("total is", total.value));     // runs immediately, auto-tracks dependencies
refreactive
HoldsAny type (primitives too)Objects, arrays, Maps, Sets
Access.value in scriptDirect property access
Reassign whole valueYes (x.value = newObj)No — replacing the variable breaks reactivity
DestructuringFineLoses reactivity — use toRefs()

Recommendation from the Vue docs: prefer ref as the primary API. shallowRef/shallowReactive for large non-deep data; readonly() to expose state safely; toRaw()/markRaw() to opt out.

computed vs watch vs methods: computed = derived value, cached; methods = called every time (event handlers or uncached work); watch = side effects in response to changes (API calls, localStorage).