Watchers — watch() & watchEffect()

Run Code When Reactive State Changes

Watchers — watch() & watchEffect()

watch lets you react to changes in specific sources; watchEffect auto-tracks every reactive read inside its callback.

5 min read Level 2/5 #vue#watchers
What you'll learn
  • Watch a specific ref with watch()
  • Auto-track with watchEffect
  • Use immediate / deep / flush options

Watchers run side effects in response to reactive change — logging, fetching, syncing to localStorage. Vue offers two flavors: watch() (explicit sources) and watchEffect() (auto-tracked).

watch — Explicit Source

import { ref, watch } from 'vue'

const count = ref(0)

watch(count, (next, prev) => {
  console.log(`went from ${prev} to ${next}`)
})

Multiple sources — pass an array:

watch([a, b], ([na, nb], [oa, ob]) => {
  // runs when either changes
})

watchEffect — Auto-Tracked

watchEffect runs immediately, tracking any reactive value read inside it, and re-runs when those values change.

import { ref, watchEffect } from 'vue'

const count = ref(0)
watchEffect(() => {
  console.log('count is', count.value)
})
// logs immediately, then again whenever count changes

Options

watch(count, fn, {
  immediate: true,  // run once on setup
  deep: true,       // deep-watch objects
  flush: 'post',    // run after DOM update
})

Cleanup

The watch callback receives an onCleanup argument for canceling stale work — useful for fetch requests and timers.

watch(id, async (newId, _old, onCleanup) => {
  const ctrl = new AbortController()
  onCleanup(() => ctrl.abort())
  const data = await fetch(`/api/${newId}`, { signal: ctrl.signal })
})
Options API vs Composition API →