Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Lifecycle Hooks  ›  Capstone Project

Watchers

Watchers 14 minwatch runs a callback when a reactive source changes, the right tool for side effects like saving or fetching.

Watchers

Shelf forgets everything on refresh. You want the books saved to the browser's storage every time the list changes, and a book's cover fetched whenever the selected book changes. Neither is a value to display, so computed is the wrong tool. These are side effects triggered by a change: the job of watch.

The rule

Computed returns a value; watch does something when a value changes.

watch takes a source and a callback. When the source changes, the callback runs with the new and old values:

import { ref, watch } from 'vue'

const selectedId = ref(1)
const cover = ref(null)

watch(selectedId, async (newId, oldId) => {
  const res = await fetch(`/api/books/${newId}/cover`)
  cover.value = await res.json()
})

What can be a source:

  • A ref: watch(selectedId, ...).
  • A getter function: watch(() => filters.genre, ...). You need this for a property of a reactive object. watch(filters.genre, ...) passes a plain string, which cannot be watched.
  • A reactive object: watch(filters, ...) watches it deeply, every nested property.
  • An array of these, to react to any of several sources.

Options go in a third argument:

  • deep: true reacts to changes inside nested objects or arrays. Watching a ref that holds an array fires only when .value is replaced; add deep to catch a push or a flipped flag inside a book.
  • immediate: true runs the callback once right away, not just on the first change.
watch(books, (list) => {
  localStorage.setItem('shelf', JSON.stringify(list))
}, { deep: true, immediate: true })

watchEffect is the automatic version: you give it one function, it runs immediately, and it re-runs whenever any reactive value it read changes. No source to list, but also no old value.

watchEffect(() => {
  document.title = `Shelf (${books.value.length})`
})

The shortcut

Ask "Do I want a value, or an action?" A value to show → computed. An action such as saving, fetching, logging or touching something outside Vue → watch. Then ask "Is my source a ref, a getter or a reactive object?"

Saving the shelfStep 1 of 4
  1. Value or action?

    Writing to localStorage is an action. Use a watcher.

Drills

Answer fast — trust the rule.

quick drill

Which job belongs in a watcher rather than a computed?

quick drill

filters is reactive. How do you watch only filters.genre?

quick drill

books is a ref holding an array. watch(books, save) does not fire when a book's read flag changes. What fixes it?

quick drill

What does immediate: true add?

quick drill

How does watchEffect differ from watch?

Remember

  • watch(source, callback, options) runs side effects when a source changes; watchEffect tracks automatically.
  • Shortcut: value → computed, action → watch; then name the source correctly.
  • Trap: watching obj.prop directly instead of a getter, and forgetting deep for changes inside arrays.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainSave on every change

Shelf should save the books array to localStorage whenever it changes, including when a single book's read flag flips, and also once right away. Write the watcher and explain each option.