SoFunction
Updated on 2025-04-06

Best Usage of Watch in Vue3

The watch function is used to listen for changes in a certain value. When the value changes, the corresponding processing logic is triggered.

1. Basic examples of watch

<template>
  <div>
    <div>{{ count }}</div>
    <button @click="changCount">ChangecountValue of</button>
  </div>
</template>
 
<script setup>
import {ref,reactive, watch} from 'vue'
const count = ref(0)
function changCount(){
  ++
}
watch(count,(newValue,oldValue)=>{
  if(newValue){
    (`I've heardcountChanges in state,The current value is${newValue},Thus dealing with related logic`);
  }
})
</script>
 
<style>
 
</style>

2. Watch to listen to multiple data

getter function:

<template>
  <div>
    <div>{{ x }}</div>
    <button @click="changCount">ChangecountValue of</button>
  </div>
</template>
 
<script setup>
import { ref, reactive, watch } from "vue";
const x = ref(1);
const y = ref(5);
function changCount() {
  ++;
}
watch(
  () =>  + ,
  (sum) => {
    (`I amxandyThe sum of${sum}`);
  }
);
</script>
 
<style>
</style>

Arrays of multiple sources

<template>
  <div>
    <div>{{ x }}</div>
    <button @click="changCount">ChangecountValue of</button>
  </div>
</template>
 
<script setup>
import { ref, reactive, watch } from "vue";
const x = ref(1);
const y = ref(5);
function changCount() {
  ++;
}
watch(
  [x,y],
  ([x,y]) => {
    (`I amx=>${x},I amy=》${y}`);
  }
);
</script>
 
<style>
</style>

3. The value of the watch monitor object

<template>
  <div>
    <div>{{  }}</div>
    <button @click="changObj">ChangecountValue of</button>
  </div>
</template>
 
<script setup>
import { ref, reactive, watch } from "vue";
const obj = ref({name:'Hello'})
function changObj(){
  +='I'm not good'
}
watch(()=>,(name)=>{
  (name);
})
</script>
 
<style>
</style>

4. Configuration parameters of watch listener

Used to enable deep monitoring

<template>
  <div>
    <div>{{  }}</div>
    <button @click="changObj">ChangecountValue of</button>
  </div>
</template>
 
<script setup>
import { ref, reactive, watch, watchEffect } from "vue";
const obj = ref({name:'Hello'})
function changObj(){
  +='I'm not good'
}
// obj is a RefImpl object. When deep monitoring is not enabled, the monitoring obj cannot detect changes in obj attributewatch(obj,()=>{
  ();
}, { deep: true })
</script>
 
<style>
</style>

Whether to enable initialization detection? The default is that the method in the listener will be executed when the value changes. After turning on immediate, the initialization will be executed once.

<template>
  <div>
    <div>{{  }}</div>
    <button @click="changObj">ChangecountValue of</button>
  </div>
</template>
 
<script setup>
import { ref, reactive, watch, watchEffect } from "vue";
const obj = ref({name:'Hello'})
function changObj(){
  +='I'm not good'
}
// obj is a RefImpl object. When deep monitoring is not enabled, the monitoring obj cannot detect changes in obj attributewatch(obj,()=>{
  ();
}, { deep: true,immediate:true })
</script>
 
<style>
</style>

5. Simplify watch through watchEffect()

It is common for listener callbacks to use the exact same responsive state as the source. For example:

<template>
  <div>
    <div>{{  }}</div>
    <button @click="changObj">ChangecountValue of</button>
  </div>
</template>
 
<script setup>
import { ref, reactive, watch, watchEffect } from "vue";
const obj = ref({name:'Hello'})
function changObj(){
  +='I'm not good'
}
watch(,()=>{
  ();
})
</script>
 
<style>
</style>

We can use the watchEffect function to simplify the above code.watchEffect()Allows us to automatically track callbacks to responsive dependencies. The listener above can be rewritten as:

<template>
  <div>
    <div>{{  }}</div>
    <button @click="changObj">ChangecountValue of</button>
  </div>
</template>
 
<script setup>
import { ref, reactive, watch, watchEffect } from "vue";
const obj = ref({name:'Hello'})
function changObj(){
  +='I'm not good'
}
// watch(,()=>{
//   ();
// })
watchEffect(()=>{
  ();
})
</script>
 
<style>
</style>

Note: It should be noted that the watchEffect callback will be executed immediately, and there is no need to specify immediate

6. watch vs. watchEffect

Both watch and watchEffect can responsively execute callbacks with side effects. The main difference between them is the way to track responsive dependencies:

  • watch only tracks explicitly listened data sources. It won't track anything accessed in the callback. Also, the callback is triggered only if the data source does change. Watch avoids tracking dependencies when side effects occur, so we can control the triggering timing of the callback function with more precise accuracy.
  • watchEffect will track dependencies during side effects. It automatically tracks all accessible responsive properties during synchronous execution. This is more convenient, and the code tends to be more concise, but sometimes its responsive dependencies are less explicit.

7. Callback trigger mechanism and stop listener

If you want to access the DOM updated by Vue in the listener callback, you need to specify the flush: 'post' option:

watch(source, callback, {
  flush: 'post'
})
 
watchEffect(callback, {
  flush: 'post'
})

Stop listening

Listeners created with synchronization statements in setup() or <script setup> will be automatically bound to the host component instance and will automatically stop when the host component is unloaded. So, in most cases, you don't need to care about how to stop a listener.

One key point is that the listener must be created with a synchronous statement: If you create a listener with an asynchronous callback, it will not be bound to the current component, and you have to stop it manually in case of memory leaks. The following example:

// ...When the listener is no longer neededunwatch()

This is the end of this article about the best usage of watch in Vue3. For more information about the usage of watch in Vue3, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!