← Back to all snippets
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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs