Computer scienceFrontendVue.jsComputable Properties

Watch and WatchEffect

3 minutes read

Vue 3 introduces a robust set of tools for managing reactivity, providing developers with enhanced control over state changes. If you're already familiar with the watch method, you're in for an expanded understanding as we delve into the watchEffect function. In this topic, we'll explore the nuances between watch and watchEffect, unlocking their potential to enhance your control over reactivity and elevate your development experience.

Revising watch function

The watch function allows developers to reactively watch a specific piece of state and execute a callback function when that state changes. This is particularly useful when you need to perform asynchronous or more complex operations in response to changes in your application's data.

Here's a brief example of how to use watch:

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

<script setup>
import { ref, watch } from 'vue';

const count = ref(0);

// Watch for changes in the 'count' variable
watch(count, (newValue, oldValue) => {
  console.log(`Count changed from ${oldValue} to ${newValue}`);
  // Perform additional actions here
});

const increment = () => {
  count.value++;
};
</script>

The above example utilizes the watch function to monitor changes in the count variable, triggering a callback that logs the old and new values to the console when a change occurs.

Understanding watcheffect

While watch requires explicit tracking of the dependencies, watchEffect is a more straightforward alternative. The watchEffect function automatically tracks all reactive dependencies used during its execution, eliminating the need to explicitly define what to watch.

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

<script setup>
import { ref, watchEffect } from 'vue';

const count = ref(0);

// Watch for changes in the count and log the value
watchEffect(() => {
  console.log(`Count is now ${count.value}`);
});

const increment = () => {
  count.value++;
};
</script>

In this case, any reactive dependency accessed within the watchEffect callback is automatically tracked, simplifying the reactivity setup.

Comparing watch and watcheffect

To better understand the differences, let's compare watch and watchEffect. Here's a simple example to illustrate the differences using a hypothetical scenario. Imagine you have a form with two input fields, and you want to perform a calculation whenever either of the input fields changes.

<template>
  <div>
    <label for="input1">Input 1:</label>
    <input id="input1" v-model="input1" />

    <label for="input2">Input 2:</label>
    <input id="input2" v-model="input2" />

    <p>Result: {{ result }}</p>
  </div>
</template>

<script setup>
import { ref, watch, watchEffect } from 'vue';


const input1 = ref(0);
const input2 = ref(0);
const result = ref(0);


watch([input1, input2], ([newInput1, newInput2], [oldInput1, oldInput2]) => {
  console.log(`Watch: Input1 changed from ${oldInput1} to ${newInput1}`);
  console.log(`Watch: Input2 changed from ${oldInput2} to ${newInput2}`);
  
  result.value = Number(newInput1) + Number(newInput2);
});

watchEffect(() => {
  console.log(`WatchEffect: Input1 is ${input1.value}`);
  console.log(`WatchEffect: Input2 is ${input2.value}`);

  result.value = Number(input1.value) + Number(input2.value);
});
</script>

Two watchers, one utilizing watch and the other watchEffect, monitor changes in the inputs. When values change, the watchers log old and new values, updating the sum displayed in the template. The output includes console logs that reflect changes in input values, aiding in understanding the reactivity flow. For instance, entering 3 in "Input 1" and 4 in "Input 2" triggers console logs and updates the displayed result to 7 in real-time.

Best practices

  • Use Watch for Explicit Dependencies: When you have specific dependencies to watch, prefer using watch to clearly define what triggers the callback.

  • Simplify with WatchEffect: For simpler scenarios where you want to reactively execute code without explicitly specifying dependencies, opt for watchEffect for concise and straightforward reactivity.

  • Consider Performance Impact: Keep in mind that watch allows you to fine-tune reactivity, but it comes with the cost of additional complexity. Use watchEffect when simplicity and automatic dependency tracking are sufficient.

Conclusion

The watch function offers explicit tracking of dependencies, making it suitable for scenarios where precise control is needed. On the other hand, watchEffect simplifies reactivity by automatically tracking all dependencies, enhancing simplicity in less complex scenarios. As a best practice, developers should carefully consider the performance impact of their choice. While watch provides fine-tuned control, watchEffect offers simplicity with automatic dependency tracking.

How did you like the theory?
Report a typo