Vue.js Computed vs Watchers?

October 5, 2020

When first starting off with Vue, it may be confusing why both the computed property and watcher both exist, when they both appear to do a similar thing, of watching for a change, then running some code.

But there is some key differences, and one of these is if we need to watch multiple pieces of data.

The Vue docs show this great example where we have a first name and last name:

data() {
  return {
    firstName: "Chris",
    lastName: "Dixon",
    fullName: "",
  };
},
watch: {
  firstName(val) {
    this.fullName = val + " " + this.lastName;
  },
  lastName(val) {
    this.fullName = this.firstName + " " + val;
  },
},

For this, we would need to create 2 watchers for the first and last name to construct the full name we need.

For this case, a computed property would be better, since we can reference multiple pieces of reactive data, and it will run if any of them changes:

data() {
  return {
    firstName: "Chris",
    lastName: "Dixon",
  };
},
computed: {
  createFullName() {
    return this.firstName + " " + this.lastName;
  },
}

Resulting in a much cleaner example.

Considering this exact same example, notice here we are taking in some data, and returning a new value. This value can be accessed in the template using the computed name of createFullName. This is perfectly valid with a computed property and the correct way to use it.

But we should not try to use them to change external data or state like this:

data() {
  return {
    firstName: "Chris",
    lastName: "Dixon",
    fullName: "",
  };
},
computed: {
  createFullName() {
    this.fullName = this.firstName + " " + this.lastName;
  },
}

Above we have an empty data property called fullName, and we attempt to set this inside of the computed property.

This results in what is called a side effect, which will throw an error. So the key here is to use a computed property when we want to observe a change and return a new value and if we want to update our data or state, this can be done by using a watcher.

computed vs watchers summary

To summarise, we can use a watch property when we want to run a function when data changes, if we instead want to return a new value based of some existing data, then we would use computed.

Also computed allows us to watch multiple data sources more efficiently too.

As we looked at in the in the above examples, we should not use computed properties to directly mutate state, and it is also not used for asynchronous operations.

So, if we had an async task such as calling for some API data which may take some time to come back from a server, a watcher is the way to go.

Computed properties are directly accessible from the template, so we can use or output the new returned value.

Another difference is that computed properties are cached. Imagine a data property is being observed by both a computed and a watch property. If this data is updated, but the value remains the same, a computed property will not re calculate since the value has not changed. However the watch property will still run the callback function regardless.

As you can see both have their uses and advantages for different use cases.