Vue.js offers a mechanism that tracks changes in the application state. This feature is called watcher, — it lets you monitor changes to reactive properties and execute custom logic in response.
What is a Watcher?
A watcher in Vue.js is a function that observes a reactive property (e.g., ref or reactive) and triggers a callback whenever the property changes. Watchers are often used for tasks like:
Logging state changes
Triggering side effects (e.g., network requests)
Synchronizing state between components or external systems
Implementing Watchers: Step-by-Step Guide
Let’s walk through an example to understand watchers better.
Basic Setup
First, create a Vue.js application and define a reactive property. On every button click it will log the message to the console because we change the value of the count.
The newValue and oldValue might not update as expected because Vue tracks objects differently. To fix this, watch specific properties using a getter function:
This ensures the watcher tracks the number property correctly.
Using reactive instead of ref
For less verbosity, consider using reactive:
const count = reactive({ number: 0, otherProp: "Hello" });watch(() => [count.number, count.otherProp], ([newNum, newOther], [oldNum, oldOther]) => { console.log(`Number: New = ${newNum}, Old = ${oldNum}`); console.log(`OtherProp: New = ${newOther}, Old = ${oldOther}`);});
With reactive:
No need to use .value
Properties are automatically unwrapped
Watching Multiple Properties
You can also watch multiple properties by passing an array to the watcher:
watch( () => [count.number, count.otherProp], ([newNum, newOther], [oldNum, oldOther]) => { console.log(`Number changed: New = ${newNum}, Old = ${oldNum}`); console.log(`OtherProp changed: New = ${newOther}, Old = ${oldOther}`); });
Here, both count.number and count.otherProp are monitored. The watcher triggers whenever either property changes..
When to Use Watchers?
Watchers are ideal for scenarios where you need to respond to changes in reactive data without directly binding the logic to the template. Some use cases include:
Fetching data when a value changes (e.g., filtering a list)
Debouncing or throttling input
Monitoring specific state changes for analytics
Best Practices
Avoid Overusing Watchers: If possible, use computed properties or v-model or simpler reactivity needs
Be Specific: Use getters to monitor specific parts of complex objects
Use Reactive for Objects: : Prefer reactive for simpler syntax with objects
Combine with Lifecycle Hooks: Integrate watchers with hooks like onMounted for initializing logic