Watchers in Vue.js

Dead Simple Chat Team

Table of Contents

In this blog post, we will understand vue watchers, how they are used in the real world and also build some examples using the watchers.

Vue.js offers some powerful features like computed properties, lifecycle hooks, refs and watchers. In the blog post we will learn about watchers and how they are used.

💡
If you are looking for a JavaScript Chat API, DeadSimpleChat is the perfect service for you.

What is a Watcher?

Watchers allow you to observe a property in Vue.js and trigger a method when it changes.

Watcher provides you with the old as well as the new value assigned to the property.

Watchers are useful in performing "side effect" reactions to state changes, for e.g performing an operation when something changes, like when an input changes automatically computing the result of the input.

Basic Example

Consider the basic example of watchers in Vue.

export default {
  data() {
    return {
      value: 0,
      square: 0
    }
  },
  template: "<input v-model='value' /> Square is: {{ square }}",
  watch: {
    value(newValue, oldValue) {
      this.square = newValue * newValue;
    }
  }
}

The code is very simple, we created an input and used the v-model attribute to save the contents of the input into the value variable.

Then we have created a watcher on the value variable. Creating a watcher is very simple, we just need to create a function inside the watch: { } object matching the name of the variable we want to watch.

When the value of that variable changes, the watcher method matching the variable name is executed.

Inside our watch function, we are multiplying the newValue with itself and storing it in a variable named square.

You can test the result in the above codepen, type a number in the input box and it will be automatically squared.

Deep Watchers

By default the watcher is only triggered when the whole value of the watched property changes.

If your watched property is an object or an array, and if the nested value of the object or array changes the watcher will not trigger.

To enable triggering the changes on nested properties, you would have to enable deep option in the watcher.

✴️
Deep Option requires traversing all the nested properties in the watched object and depending upon the size of the object it would be computationally expensive. Hence you should use this object with caution and do not use it in on very large objects. 
const { createApp } = Vue;

createApp({
  data() {
    return {
      cart: [],
      itemCount: 0
    };
  },
  template: `
      <button @click='addItem("apple")'>Apple</button>
      <button @click='addItem("mango")'>Mango</button>
      <button @click='addItem("orange")'>Orange</button>
      <br />
      Cart: {{ itemCount }}
  `,
  watch: {
    cart: {
      handler(newValue, oldValue) {
        this.itemCount = this.cart.length;
      },
      deep: true
    }
  },
  methods: {
    addItem(item) {
      this.cart.push(item);
      console.log(this.cart);
    }
  }
}).mount("#app");

Check the above example, we have set the deep option to true. Each time you press the "Apple", "Orange" or "Mango" button the count will increment.

If you set the deep option to false and then press the buttons, the count will not increment.

this.$watch() to Create Watcher

It is also possible to programmatically create watchers using the $watch method.

const { createApp } = Vue;

createApp({
  data() {
    return {
      question: ""
    };
  },
  template: "<input type='text' v-model='question' placeholder='question?' />",
  created() {
    this.$watch("question", (newQuestion) => {
      console.log("Question Changed", newQuestion);
    });
  }
}).mount("#app");

If you update the input, the "Question Change" message will be printed on the console.

Here are some of our other articles: