JAVASCRIPT
Deep Watching Reactive Objects with Vue 3 `watch`
Master how to use Vue 3's `watch` function to react to changes in reactive data, including deep watching objects and arrays for comprehensive state observation.
<script setup>
import { ref, reactive, watch } from 'vue';
const count = ref(0);
const user = reactive({
name: 'Alice',
age: 30,
address: {
street: '123 Vue Lane',
city: 'Vueville'
}
});
// 1. Watching a ref (primitive or object reference)
watch(count, (newVal, oldVal) => {
console.log(`Count changed from ${oldVal} to ${newVal}`);
});
// 2. Watching a reactive object's property
watch(() => user.name, (newName, oldName) => {
console.log(`User name changed from ${oldName} to ${newName}`);
});
// 3. Deep watching a reactive object (or ref holding an object)
// The `deep: true` option is crucial for nested properties
watch(user, (newUser, oldUser) => {
console.log('User object (deep) changed:', newUser);
// Note: oldUser might be the same object reference as newUser if deep watch changes happened internally
// To get a true deep copy of old value, you'd need to manually clone it in a computed or prior watch.
}, { deep: true, immediate: true }); // immediate: true runs the watch handler immediately on setup
// 4. Watching multiple sources
watch([count, () => user.age], ([newCount, newAge], [oldCount, oldAge]) => {
console.log(`Count or age changed. Count: ${oldCount} -> ${newCount}, Age: ${oldAge} -> ${newAge}`);
});
const incrementCount = () => {
count.value++;
};
const changeUserName = () => {
user.name = 'Bob';
};
const changeUserAge = () => {
user.age++;
};
const changeUserStreet = () => {
user.address.street = '456 Composition St';
};
</script>
<template>
<div>
<h1>Vue 3 Watchers</h1>
<p>Count: {{ count }}</p>
<p>User: {{ user.name }}, {{ user.age }} ({{ user.address.street }})</p>
<button @click="incrementCount">Increment Count</button>
<button @click="changeUserName">Change User Name</button>
<button @click="changeUserAge">Change User Age</button>
<button @click="changeUserStreet">Change User Street (Deep Watch)</button>
<p>Check console for watch logs.</p>
</div>
</template>
How it works: This snippet demonstrates various ways to use Vue 3's `watch` function for observing reactive data changes. It covers watching a `ref` (primitive), a specific property of a `reactive` object, and crucial `deep` watching of an entire `reactive` object to detect changes within its nested properties. The `immediate` option is also shown, which executes the watch handler immediately upon component setup. Finally, watching multiple sources simultaneously is illustrated, providing fine-grained control over when side effects should run based on data mutations.