Easy Tutorial
❮ Vue3 Components Home ❯

Vue3 Watchers

In this section, we will introduce Vue3's watch property. We can use watch to respond to data changes.

The following example demonstrates a counter implemented using watch:

Example

<div id="app">
    <p style="font-size:25px;">Counter: {{ counter }}</p>
    &lt;button @click="counter++" style="font-size:25px;">Click Me</button>
</div>

<script>
const app = {
    data() {
        return {
            counter: 1
        }
    }
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('counter', function(nval, oval) {
    alert('Counter value changed from: ' + oval + ' to ' + nval + '!');
});
</script>

The following example performs conversion between kilometers and meters:

Example

<div id="app">
    Kilometers: <input type="text" v-model="kilometers" @focus="currentlyActiveField = 'kilometers'">
    Meters: <input type="text" v-model="meters" @focus="currentlyActiveField = 'meters'">
</div>
<p id="info"></p>
<script>
const app = {
    data() {
        return {
            kilometers: 0,
            meters: 0
        }
    },
    watch: {
        kilometers(newValue, oldValue) {
            // Check if the current input field is kilometers
            if (this.currentlyActiveField === 'kilometers') {
                this.kilometers = newValue;
                this.meters = newValue * 1000;
            }
        },
        meters(newValue, oldValue) {
            // Check if the current input field is meters
            if (this.currentlyActiveField === 'meters') {
                this.kilometers = newValue / 1000;
                this.meters = newValue;
            }
        }
    }
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('kilometers', function(newValue, oldValue) {
    // This callback will be invoked after vm.kilometers changes
    document.getElementById("info").innerHTML = "Previous value: " + oldValue + ", New value: " + newValue;
});
</script>

Click the "Try it out" button to see the live example.

In the above code, we created two input fields with initial values of 0 for both kilometers and meters in the data property. The watch object creates two monitoring methods for the data object: kilometers and meters.

When we input data into the fields, the watch will listen for real-time changes and update the values accordingly. You can see the demonstration in the following video:

Using watch with Asynchronous Loading

For asynchronous data loading, Vue provides a more general method through the watch option to respond to data changes.

The following example uses the axios library, which will be introduced later.

Example

<!-- Since the ecosystem of AJAX libraries and general-purpose tools is quite rich, Vue core code does not duplicate -->
<!-- these functionalities to stay lean. This also allows you to freely choose the tools you are more familiar with. -->
<script src="https://cdn.staticfile.org/axios/0.27.2/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue/3.2.37/vue.global.min.js"></script>
<script>
const watchExampleVM = Vue.createApp({
    data() {
        return {
            question: '',
            answer: 'Questions should end with a question mark (?).'
        }
    },
    watch: {
        // This function will run whenever the question changes, compatible with both English and Chinese question marks
        question(newQuestion, oldQuestion) {
            if (newQuestion.indexOf('?') > -1 || newQuestion.indexOf('?') > -1) {
                this.getAnswer();
            }
        }
    },
    methods: {
        getAnswer() {
            this.answer = 'Loading...';
            axios
                .get('/try/ajax/json_vuetest.php')
                .then(response => {
                    this.answer = response.data.answer;
                })
                .catch(error => {
                    this.answer = 'Error! Unable to access the API. ' + error;
                });
        }
    }
}).mount('#watch-example');
</script>
❮ Vue3 Components Home ❯