Lesson 2 of 7
Reactivity: ref & reactive
You will learn how Vue tracks data with `ref` and `reactive` and updates the page when it changes. Knowing when to use each avoids the most common Vue mistakes.
<template>
<div>
<!-- Access ref values with .value in <script>, directly in template -->
<p>Count: {{ count }}</p>
<p>Name: {{ name }}</p>
<p>Items: {{ items.join(', ') }}</p>
<button @click="increment">+</button>
<button @click="addItem">Add Item</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
// ref() — for primitives (number, string, boolean) and anything you might reassign
const count = ref(0)
const name = ref("Alice")
const items = ref([])
// In <script>, access the value with .value
function increment() {
count.value++
}
function addItem() {
items.value.push(`Item ${items.value.length + 1}`)
}
// You can reassign refs entirely
function reset() {
count.value = 0
items.value = [] // OK — reassigning the ref
}
</script><template>
<form @submit.prevent="submit">
<input v-model="form.name" placeholder="Name" />
<input v-model="form.email" placeholder="Email" type="email" />
<button type="submit">Submit</button>
<pre>{{ form }}</pre>
</form>
</template>
<script setup>
import { reactive, computed, watch } from 'vue'
// reactive() — for objects (no .value needed)
const form = reactive({
name: "",
email: "",
})
// computed() — derived reactive value, cached
const isValid = computed(() =>
form.name.length > 0 && form.email.includes("@")
)
// watch() — run a function when a value changes
watch(() => form.email, (newEmail) => {
console.log("Email changed to:", newEmail)
})
function submit() {
if (!isValid.value) return alert("Invalid form")
console.log("Submitting:", { ...form })
form.name = ""
form.email = ""
}
</script>Common question
Does Vue re-render the whole component when data changes?
Vue makes data reactive by intercepting reads and writes. While rendering, it records which values were read; when one of them changes, exactly the effects that depended on it run again. That is why updates are precise and why you rarely have to think about optimisation in Vue.
Declare state with ref, derive values with computed, react to changes with watch or watchEffect when you really need a side effect, and avoid reactive objects. Keep templates declarative and let Vue's tracking decide what to update.
Source: Vue's documentation describes its core as "a reactivity system that tracks dependencies at a fine granularity".
Common mix-ups
Each of these sounds reasonable. Think about why it is wrong, then open the explanation.
The component has to run again, like in React, so everything gets rebuilt.
ref and reactive are interchangeable ways to make data reactive.
A computed is the same as a that returns the value.
Tip: use the ← and → keys to move between lessons.