Performing A Deep Watch In Vue.js

A tutorial on how to perform a deep watch over an array of objects in Vue.js

ยท

4 min read

Performing A Deep Watch In Vue.js

If you are a vue.js developer like me, you've definitely come across Watch (Watchers). In this tutorial we are going to have look at what a watcher is and how we use watch over arrays of object.

What is watcher?

A Watcher is a useful and special feature provided by VueJs to watch over a component or data property and perform specific actions when the value of the component or data property is changed. It is the most generic and recommended way to react over a data change in a vue instance. When we are performing asynchronous operations like calling the API, or dealing with promises, watcher is the most recommended way to perform logical operations when data gets changed.

Basic example of watcher.

In this example, we are converting the user input of the kilometer value into miles

  • Let's first prepare our template to display the results inside the App.vue file as shown below:
<template>
  <div id="app">
    <h1>Basic Example for the <a href="https://vuejs.org/guide/essentials/watchers.html#basic-example" class="watch">watchers</a> in vue.js</h1>

    <label for="km">Enter KM to get the mils:</label>
    <input type="number" id="km" v-model="km">

    <p class="result">Converted Miles: {{miles}}</p>
  </div>
</template>
  • Now, we have to write the logic to find the miles when the user changed the value of kilometer. Here the watcher comes in play, we have to watch for value of km when it's value changed we have to update the miles output.
  • Enter the following code snipper into the script tag:
export default {
  name: "App",
  components: {},
  data () {
    return {
      miles: 0,
      km: 0,
    }
  },
  watch: {
    km (newVal, oldVal) {
      this.miles = (this.km * 0.6214).toFixed(2)
    }
  }
};
  • In this way, we can use watcher to perform operations when a piece of data changes. Here is the link for the code that we discussed here.

Deep watcher over array of objects.

  • Let's create a dummy array of objects using the following code snippet:
users: [
  { id: 1, name: "shiv" },
  { id: 2, name: "Jhon" },
  { id: 3, name: "Mariya" },
]
  • Now, we have to create a Vue SFC User.vue using the following code:
<template>
  <div class="main">
    <p class="id">{{ userData.id }}:</p>
    <div class="left-section">
      <input type="text" v-model="user.name" />
      <p class="display">New Value: {{ newDisplay }}</p>
      <p class="display">Old Value: {{ oldDisplay }}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: "User",
  props: {
    userData: {
      type: Object,
      default: () => {},
    },
  },
  data: () => {
    return {
      user: null,
      newDisplay: "",
      oldDisplay: "",
    };
  },
  created() {
    this.user = JSON.parse(JSON.stringify(this.userData));
    console.log(this.user);
  },
  watch: {
    "user.name": function (newVal, oldVal) {
      this.newDisplay = newVal;
      this.oldDisplay = oldVal;
    },
  },
};
</script>
  • After creating the User.vue, we have to import it in the App.vue file and pass users as a prop. In User.vue, we are using watcher over the value which is changing and we are also using user.name property instead of user so that vue can detect the change happening to user.name. Because of this, we will not be changing the user object but we will be changing the name key inside the user object.
  • Now, add the following lines in the App.vue file:
<template>
  <div id="app">
    <user v-for="(item, index) in users" :key="index" :userData="item" />
  </div>
</template>

<script>
import User from "./components/User";
export default {
  name: "App",
  components: { User },
  data() {
    return {
      users: [
        { id: 1, name: "shiv" },
        { id: 2, name: "Jhon" },
        { id: 3, name: "Mariya" },
      ],
    };
  },
};
</script>
  • Now whenever the user is changing the value of the input field, we can see that the value of the below paragraph is also changing.

There is another way to perform Deep watch over objects or an array of a object.

Second way to perform deep watch:

  • Add the following lines into your console:
<script>
export default {
  props: {
    userData: {
      type: Object,
      default: () => {},
    },
},
  watch: {
    user: {
    handler:function(newVal) {
      console.log("new Value is " + newVal)
    },
     deep:true
    },

  }
};
</script>
  • In this way, we only get the new value or you can say the updated value of the property. We are not going to get the old value.

NOTE: If you also want to run your watcher at the time of initialization, you have to add immediate: true inside your watcher like this:

watch: {
user: {
    immediate: true,
    handler:function(newVal) {
      console.log("new Value is " + newVal)
    },
     deep:true
    },
},

You can play with the deep watcher code here

Conclusion

By this using the methods mentioned in this article, we can perform a deep watch inside vue.js over an array of objects. Sometimes it's hard to detect changes in 2-3 level nested objects or data. Insuch cased twe can use deep watcher to do our task. I hope this helps you understand the concepts of deep watcher in VueJs.

Thanks ๐Ÿ™

ย