Vuejs 3 Watch

Posted on  by admin

Watch API with Reactive

Modified2 years ago. I am working on a VueJS application where I want to watch for a change in the state of a user from the vuex store and do something. The changes are happening but the watch hook is not being triggered. This is the code of the computed property and the watch. 322322 bronze badges. In your user computed method, you're not return-ing a value. I suspect if you look in Vue devtools, computed: user has a value of undefined.

I believe your change should be..

Web development, programming languages, Software testing & others

export default {
watch: {
name: function() {

đź”—Composition API - watchEffect

  • 11 gold badge1010 silver badges1515 bronze badges. 1515 bronze badges. The watch API is part of the larger Vue Composition APIs.
  • It takes a data source and a callback function that executes when the provided data changes.
  • In my experience, I’ve found that whenever I need to track reactive data and perform some operation when the data changes, computed properties were all I needed.
  • However, like the Options API, the Vue Composition API also shipped with watch, that offers developers another way of watching and reacting to data changes.
  • I have found that there’s some nuance around it and I wanted to deep dive into it in this post and shine more light on the different ways you can use it.

đź”—Composition API - watch

This is largely because it behaves differently depending on the type of data you’re watching, and it can get confusing if you’re not already familiar with it.

Watching a nested object

In this post, we’ll look at how to use it when dealing with ref and reactive states as well as with arrays and objects.

A general rule of thumb when working with the watch API is to know that it takes two arguments. The first is the data source you want to watch and the second is a callback function that applies side effects to that data.

The examples that will follow is based on simple data types like: numbers, strings booleans.

You can skip to examples on complex data types (arrays and objects).

The watch API allows us to watch a single ref or to collectively watch multiples refs.

Let's demonstrate how to watch a single ref with simple data types (strings, numbers booleans).


When watching a single ref, we simply pass it as the first argument to the watch API.

Here’s a quick example:. This is fairly straightforward.

We are watching name to ensure that when its value changes, we perform any operation we want in the callback.

In this case, we just log the current and old values to the console.

The same applies to all other ref's of simple data types like booleans and numbers.

However that's not the case when watching a ref of more complex data type like arrays and objects.

Complex data types.

Let's see how to do that with an array:.

Two things to notice here:.

import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
new Vue({
render: h => h(App)

We used a function to return the array we want to watch (not passed in directly like we did in the last example).


We returned a copy of the values of the array i.e ..level.value (not the existing array itself).

The difference here is that with objects, we pass the data directly into the watch API, no need to return it with a function or make a copy like we did with the array. One more thing you'll notice is that for both cases (array and object), the value of currentValue and oldValue is in fact the same thing.

here's why and how to fix it. What if we had nested objects or arrays, how do we use the watch API to monitor changes in nested arrays/objects?

Let's start with a nested array example:.

We are watching level, which is the parent of the nested secondLevel array.

Ideally, when the value of secondLevel changes, the watch API should execute and log the different values to the console.

However, that won't happen becuase:. Watching a reactive object or array will always return a reference to the current value of that object for both the current and previous value of the state.

To fully watch deeply nested objects and arrays, a deep copy of values may be required.

This can be achieved with a utility such as lodash.cloneDeep.

As a result, we can use lodash to "deeply" watch the level array (this time with access to the nested secondLevel array):.

With this, the values of both our arrays will be tracked just fine.

The good thing with this approach is that we did't have to copy the array's values anymore, we can simply pass it into cloneDeep() and it handles the rest for us.

This also applies to nested objects:.

import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
new Vue({
el: '#app',
template: '',
components: { App }
console.log('Vue version: ' + Vue.version)

If we had more than one item that we wanted to watch at once, we can pass them all into the watch API with an array.

For instance, if we had firstName and lastName, we could watch for changes in their values at once like so:.

Watching multiple ref's

The way the watch API handles ref values is somewhat different from how it handles reactive.

Everything we've done so far has been with ref values, let's try redoing them, but this time with reactive. This way, we'll cover both values and you will be equipped to use the watch API either way.

Once again we start off with an array.

Here's how to watch a reactive array and react to changes in its value:.

Using the watch API with a reactive array is no different from how we used it with a ref.

In both cases, we deep cloned the array with lodash and return it as the first argument to the watch API.

The only difference here is that we did not append .value to read the value of the level array.

To cut to the chase quickly, using lodash like we did in the last example ensures that we track every aspect of the data we want to watch.

As a result, if we have deeply nested arrays, it will track the values as well:.

This is almost exactly the same with the ref example, with the exception of the .value appends.

When dealing with objects, I personally tend to go with reactive by default.

However the implementation is also not very different from how you would approach a ref:.

import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
export const myMixin = {
data() {
return {
title: "Mixins are cool",
copyright: "All rights reserved. Product of super awesome people"
created: function() {
methods: {
greetings: function() {
console.log("Howdy my good fellow!" + this.title);
new Vue({
mixins: [myMixin],
render: h => h(App)

You can watch an object or an array by deep cloning it using lodash.


I have made this approach my default since in most cases, I want to track both the previous and current values of the data I'm watching. If you're okay tracking just the current values, you don't need to use lodash here.

đź”—Options API - watch in the Options API

The watch API can also take a third argument deep, which when set to true, will extend its functionality to keep an eye on deeply nested values:. However, because it doesn't track both previous and current values of state, lodash is still my preferred option for using the watch API with reactive nested arrays and objects:.