← Back to all snippets
JAVASCRIPT

Reacting to Data Changes with watch and watchEffect

Efficiently observe and react to changes in reactive data within Vue 3 components using the `watch` and `watchEffect` functions from the Composition API for various scenarios.

import { ref, watch, watchEffect, onMounted } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const multiplier = ref(2);
    const computedValue = ref(0);

    // 1. watch: Explicitly watches one or more reactive sources
    watch(count, (newCount, oldCount) => {
      console.log(`watch: Count changed from ${oldCount} to ${newCount}`);
      // Perform side effect, e.g., API call, complex calculation
      computedValue.value = newCount * multiplier.value;
    }, { immediate: true }); // immediate: true runs the callback immediately upon watcher creation

    // Watch multiple sources
    watch([count, multiplier], ([newCount, newMultiplier], [oldCount, oldMultiplier]) => {
      console.log(`watch: Count or Multiplier changed. New values: ${newCount}, ${newMultiplier}`);
      computedValue.value = newCount * newMultiplier;
    });

    // 2. watchEffect: Automatically tracks dependencies and re-runs on any change
    const stopWatchEffect = watchEffect(() => {
      const result = count.value * multiplier.value;
      console.log(`watchEffect: Current product is ${result}`);
      // No need to pass dependencies explicitly, it just 'reacts'
      // This is ideal for side effects that depend on multiple reactive state pieces
    });

    // Stop watchEffect after 5 seconds for demonstration
    onMounted(() => {
      setTimeout(() => {
        stopWatchEffect();
        console.log('watchEffect stopped.');
      }, 5000);
    });

    const increment = () => { count.value++; };
    const increaseMultiplier = () => { multiplier.value++; };

    return {
      count,
      multiplier,
      computedValue,
      increment,
      increaseMultiplier
    };
  }
};

/*
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment Count</button>

    <p>Multiplier: {{ multiplier }}</p>
    <button @click="increaseMultiplier">Increase Multiplier</button>

    <p>Computed Value (via watch): {{ computedValue }}</p>
    <p>Check console for watch and watchEffect logs.</p>
  </div>
</template>
*/
How it works: This snippet showcases Vue 3's `watch` and `watchEffect` functions for reacting to changes in reactive data. `watch` allows you to explicitly observe one or more reactive sources and perform side effects when they change, offering fine-grained control over new and old values. `watchEffect`, on the other hand, automatically tracks all reactive dependencies accessed within its callback and re-runs whenever any of those dependencies change, simplifying scenarios where you need to react to multiple dynamic sources without manual dependency listing.

Need help integrating this into your project?

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

Hire DigitalCodeLabs