JAVASCRIPT
Reacting to State Changes with watch and watchEffect
Explore Vue 3's `watch` and `watchEffect` functions to respond to changes in reactive data, enabling side effects like data fetching or DOM updates based on state changes.
<script setup>
import { ref, watch, watchEffect } from 'vue';
const count = ref(0);
const searchTerm = ref('');
const data = ref(null);
// --- watch() ---
// Watches a specific source (ref, reactive object, computed, or getter function)
// Provides old and new values
watch(count, (newCount, oldCount) => {
console.log(`Count changed from ${oldCount} to ${newCount}`);
// Perform side effect here
if (newCount > 5) {
console.log('Count is now greater than 5!');
}
});
// Watching multiple sources
watch([count, searchTerm], ([newCount, newSearchTerm], [oldCount, oldSearchTerm]) => {
console.log(`Multiple sources changed: Count ${oldCount} -> ${newCount}, Search ${oldSearchTerm} -> ${newSearchTerm}`);
});
// --- watchEffect() ---
// Automatically tracks its dependencies
// Runs immediately and re-runs whenever any of its dependencies change
watchEffect(async () => {
if (searchTerm.value.length > 2) {
console.log(`Fetching data for: ${searchTerm.value}...`);
// Simulate API call
data.value = `Data for "${searchTerm.value}"`;
} else {
data.value = null;
}
});
function increment() {
count.value++;
}
function updateSearchTerm(event) {
searchTerm.value = event.target.value;
}
</script>
<template>
<div>
<h1>Watchers Demo</h1>
<p>Count: {{ count }}</p>
<button @click="increment">Increment Count</button>
<hr />
<label for="search">Search Term:</label>
<input id="search" :value="searchTerm" @input="updateSearchTerm" placeholder="Type to search..." />
<p v-if="data">Result: {{ data }}</p>
<p v-else-if="searchTerm.length > 2">Searching...</p>
<p v-else>Type at least 3 characters to search.</p>
</div>
</template>
How it works: This snippet demonstrates Vue 3's `watch` and `watchEffect` functions for reacting to changes in reactive state. `watch` allows you to explicitly specify one or more reactive sources (like `ref`s or `reactive` objects) to 'watch'. It provides both the old and new values of the watched source(s), giving you fine-grained control over when and how side effects are triggered. `watchEffect`, on the other hand, automatically tracks all reactive dependencies accessed within its callback and immediately re-runs whenever any of those dependencies change. It's simpler for cases where you just want to run an effect based on current state, without needing access to previous values. Both are crucial for performing actions like data fetching, logging, or DOM manipulation in response to state changes.