Watch vs watchEffect in Vue: Key Differences and Usage
watch lets you react to specific reactive data changes with fine control, while watchEffect automatically tracks all reactive dependencies used inside its function and reruns when any change. Use watch for targeted watching and watchEffect for automatic, simpler side effects.Quick Comparison
This table summarizes the main differences between watch and watchEffect in Vue.
| Aspect | watch | watchEffect |
|---|---|---|
| Dependency Tracking | Explicit reactive source(s) passed as argument | Automatically tracks all reactive dependencies used inside the effect function |
| Use Case | Watch specific reactive data changes | Run side effects automatically when any reactive dependency changes |
| Execution Timing | Runs callback after watched source changes | Runs immediately and reruns on dependency changes |
| Cleanup Support | Supports cleanup via onInvalidate callback | Supports cleanup via onInvalidate callback |
| Complexity | More setup, more control | Simpler, less control |
| Initial Run | Does not run callback on initial setup by default | Runs effect immediately on setup |
Key Differences
watch requires you to specify exactly which reactive source(s) to observe. It only runs the callback when those sources change, giving you precise control over what triggers your code. This is useful when you want to react to specific data changes and possibly compare old and new values.
In contrast, watchEffect automatically tracks any reactive data accessed inside its function. It runs immediately when set up and reruns whenever any of those dependencies change. This makes it great for simple side effects that depend on multiple reactive sources without manually listing them.
Another difference is that watch does not run its callback on initial setup unless you set the immediate option, while watchEffect always runs immediately. Both support cleanup logic via the onInvalidate callback to handle effects like timers or subscriptions.
Code Comparison
Here is an example using watch to react to a specific reactive property change.
import { ref, watch } from 'vue'; const count = ref(0); watch(count, (newVal, oldVal) => { console.log(`Count changed from ${oldVal} to ${newVal}`); }); count.value++; count.value++;
watchEffect Equivalent
The same behavior using watchEffect automatically tracks count and reruns when it changes.
import { ref, watchEffect } from 'vue'; const count = ref(0); watchEffect(() => { console.log(`Count is now ${count.value}`); }); count.value++; count.value++;
When to Use Which
Choose watch when you need to react to specific reactive data changes, want access to old and new values, or want to control when the callback runs (e.g., not on initial setup).
Choose watchEffect when you want a simple way to run side effects that depend on multiple reactive sources without listing them explicitly, and you want the effect to run immediately and rerun automatically on any dependency change.
Key Takeaways
watch tracks specific reactive sources and runs on their changes only.watchEffect auto-tracks all reactive dependencies used inside its function and runs immediately.watch for precise control and access to old/new values.watchEffect for simpler, automatic side effects without manual dependency listing.onInvalidate.