watch VS watchEffect in Vue 3 - Must Know Differences

Robin
Updated on April 25, 2022

Knowing the differences between watch and watchEffect will give you the power to use them in the current situations. The composition API in Vue 3 provides flexibility and useful alternatives for different requirements.

Here, you can say watch and watchEffect methods are the perfect example of it. Both of them have some similarities but if you don't know their basic differences then you might face some difficulty.

The watch method is used to trigger a side-effect for the change of any specific reactive values provided to it. On the other hand, watchEffect tracks multiple reactive values automatically without explicitly mentioning them and triggers a side-effect whenever any of them changes.

Both of them trigger a side-effect for the change of reactive values. But the differences between watch and watchEffect methods are the followings:

  1. The watch method runs lazily by default. It does not get executed when the component mounts. But watchEffect runs once when the component mounts then it executes the callback function for the change of dependency variables.
  2. The watchEffect method accepts 2 arguments, a callback function and an object with some options. But watch accepts 3 arguments. The first is the list of reactive values, the second is a callback function and the third is an object with some options.
  3. In watchEffect you don't have to provide the reactive variables on which it will depend. But in the watch method, you have to specify the list of reactive variables as its first argument.
  4. In the watch method, you can access the updated and previous values of the dependent reactive variables inside the callback function. But the watchEffect does not give the updated or previous values.

Before seeing the differences between the watch and watchEffect methods with examples, let's know how you can use these methods in Vue 3 composition API.

In this article, I will use Vue 3 composition API with script setup, not options API. Because it gives much more flexibility while writing our Vue application.

watch VS watchEffect in Vue 3 - Must Know Differences

Also Read: Composition API VS Options API in Vue 3 For Beginners

How to Use watch Method in Vue 3

In composition API, you can import a watch() method from vue package. This method at the basic level will accept 2 arguments to work. This method always tracks the reactive values. You can see more about this in the Vue 3 official documentation.

The third argument is optional. If you need some advanced features or want to change the default behavior of this method then you can provide the third argument.

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

const count = ref(0);

watch(count, (newValue, oldValue) => {
    console.log(newValue);
    console.log(oldValue);
});
</script>

        

The watch() method is lazy by default i.e. it only executes the callback function when the source value has changed.

In this example, I am using a reactive variable count which is a ref as the source of the watch() method. The callback function will go in the second argument. When the value of this count variable changes watch() method will call this callback function.

This callback function will receive 2 arguments. The first is the new value of the count variable and the second is the previous value.

But how can you watch multiple reactive variables?

To watch multiple variables, you have to pass an array of reactive variables as the first argument in the watch() method.

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

const count = ref(0);
const count2 = ref(0);

watch([count, count2], ([newCount, newCount2], [oldCount, oldCount2]) => {
    console.log(`Count changed from ${oldCount} to ${newCount}`);
    console.log(`Count2 changed from ${oldCount2} to ${newCount2}`);
});
</script>

        

Here, I am passing count and count2 variables to watch. To get the new and previous values for these variables, in the callback function argument you can define 2 arrays. The first array will contain new values and the second array will contain previous values.

There is a third argument in the watch() method where you can set some options for this method. These options are immediate, flush, deep, and onTrack.

Also Read: Improve Performance in Vue 3 Using Lazy Loading and Dynamic Import

How to Use watchEffect Method in Vue 3

The watchEffect() method is first introduced in Vue 3. You have to import this method from vue package in order to use it. Unlike the watch() method, it accepts 2 arguments in total. The first is the callback function and the second is some options for this method.

You can see more in-depth about this method in the official documentation.

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

const count = ref(0);
const count2 = ref(0);

watchEffect(() => {
    console.log(`Count - ${count.value}`);
    console.log(`Count 2 - ${count2.value}`);
});
</script>

        

Inside the watchEffect() method, you don't have to set reactive variables as its source. It automatically tracks reactive variables used inside this method.

In this example, I am using count and count2 variables in the watchEffect() method. Therefore, when any one of these variables changes its value, this method will call the callback function.

This method is not lazy by default. That means it will call the callback function immediately when the component loads even if any reactive value doesn't change.

It also has a third argument where you can set some options. These options are flush, onTrack, and onTrigger.

watch VS watchEffect - All Differences with Example

As we have learned about the watch() and watchEffect() methods and how we can use them in a Vue 3 application, it will be easier for you to understand the differences between them.

Let's see those differences that you have seen at the beginning of this article in detail with some examples.

1. Lazy Loading of watch and watchEffect

You know that watch() method is lazy by default but the watchEffect() isn't. The watch() method only calls the callback function when the source values change.

But the watchEffect() calls the callback function immediately when the component mounts.

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

const count = ref(0);
const count2 = ref(0);

watchEffect(() => {
    console.log(`Count - ${count.value}`);
    console.log(`Count 2 - ${count2.value}`);
});

watch([count, count2], ([newCount, newCount2], [oldCount, oldCount2]) => {
    console.log(`Count changed from ${oldCount} to ${newCount}`);
    console.log(`Count2 changed from ${oldCount2} to ${newCount2}`);
});
</script>
        

Here, the watch() will only execute the callback function when any of the count or count2 variables change.

On the other hand, the watchEffect() method will only execute the callback function when this component mounts and also each time the count or count2 variable changes.

2. Difference in The Number of Arguments

As you have seen, these two methods are different in terms of the number of arguments it accepts. The watch() method can get 3 arguments and the watchEffect() method can get 2 arguments in total.

To use watch() method, you must provide the first 2 arguments: source variables on which it will depend and the callback function.

To use watchEffect() method, you have to provide only one argument which is the callback function in the first argument.

3. Providing Reactive Variables in watch and watchEffect

The watch() method does accept source variables. Depending on the changes of those variables, it will execute the callback function.

But the watchEffect() can track the variables used inside the callback function automatically. It doesn't need any dependency sources.

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

const count = ref(0);
const count2 = ref(0);

watchEffect(() => {
    console.log(`Count - ${count.value}`);
    console.log(`Count 2 - ${count2.value}`);
});

watch([count, count2], ([newCount, newCount2], [oldCount, oldCount2]) => {
    console.log(`Count changed from ${oldCount} to ${newCount}`);
    console.log(`Count2 changed from ${oldCount2} to ${newCount2}`);
});
</script>
        

Here, you can see watch() has an array of dependencies like count and count2 variables. But inside watchEffect() method there is nothing like that.

4. Difference in Accessing Updated and Previous Values

One of the major differences between these two methods is that in watch() method you can get the new values and the previous values of the source variables.

But in the wathcEffect() method, there is no way to get the previous values of the reactive variables used inside the callback function. You can get the new values by directly accessing those variables.

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

const count = ref(0);
const count2 = ref(0);

watchEffect(() => {
    console.log(`Count - ${count.value}`);
    console.log(`Count 2 - ${count2.value}`);
});

watch([count, count2], ([newCount, newCount2], [oldCount, oldCount2]) => {
    console.log(`Count changed from ${oldCount} to ${newCount}`);
    console.log(`Count2 changed from ${oldCount2} to ${newCount2}`);
});
</script>
        

You can see, I am getting updated values newCount, newCount2 and previous values oldCount, oldCount2 in the watch() method. I can use these inside the callback function.

In the watchEffect() method, I am using count.value and count2.vlaue to get the new values for those variables. But I don't have their previous values.

Also Read: Best Ways to Use v-model to Custom Components in Vue 3 (Absolute Guide)

When Should You Use watch and watchEffect?

After knowing the differences between watch() and watchEffect() methods, one question might come to your mind which method should you use?

Sometimes it depends on how you want to use them in your Vue 3 application. Because you can solve some problems with any of these methods.

But there are some use cases where one method shines over another. These are the situations you can consider:

  • If you want to explicitly control the dependencies which will trigger the side-effect, then you must use watch() method. Otherwise, you can use watchEffect() method.
  • If you need previous values of the dependencies then you have to use the watch() method.
  • If you want to execute the callback function immediately when the component mounts then go with the watchEffect() method. The watch() is useful when you need to perform the method lazily.

Conclusion

Both the watch() and watchEffect() methods have their own usages. Both of them can trigger side effects in a Vue 3 application. But you can take some advantage of those methods when you know the differences.

That's why in this article, I have shown you all the differences between watch and watchEffect methods in Vue 3 compositions API.

I hope next time you will be able to use them correctly in your Vue 3 application. You can watch and trigger side effects for any reactive variables.

Thank you so much for reading. Happy coding!

Related Posts