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:
- The
watch
method runs lazily by default. It does not get executed when the component mounts. ButwatchEffect
runs once when the component mounts then it executes the callback function for the change of dependency variables. - The
watchEffect
method accepts 2 arguments, a callback function and an object with some options. Butwatch
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. - In
watchEffect
you don't have to provide the reactive variables on which it will depend. But in thewatch
method, you have to specify the list of reactive variables as its first argument. - In the
watch
method, you can access the updated and previous values of the dependent reactive variables inside the callback function. But thewatchEffect
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.

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 usewatchEffect()
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!