In Vue.js computed properties are dynamic properties that are automatically updated whenever their dependencies are updated. Computed properties allow us to compose new data derived from other data.
Example
In the following example, we define a computed property called fullName
, which is dependent on the data properties firstName
and lastName
.
Because of this, whenever firstName
or lastName
is updated, fullName
will also be updated.
const Example = {
data() {
return {
firstName: '',
lastName: '',
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
}
}
First name: <input type='text' v-model='firstName'>
Last name: <input type='text' v-model='lastName'>
<p>Hello {{ fullName }}</p>
Computed properties vs. methods
Of course, this same effect could be created with a method:
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName;
}
}
<p>Hello {{ getFullName() }}</p>
However, computed properties have the advantage of a caching system - every time you invoke a computed property, it will only have to refetch its value if its dependencies have changed.
Whereas with methods, the values are always refetched, regardless of whether the dependencies have changed or not.
Computed properties to filter lists
In Part 5 of this series on List Rendering, we learned that you could filter a list of items by combining a v-if inside of a v-for. At the time I mentioned computed properties were a better tool for this sort of task, so let’s look at an example of how a computed property could be used to filter a list of items:
data() {
return {
spanishWords: ['hola', 'adios', 'uno', 'dos'],
}
},
computed: {
shortSpanishWords() {
// Filter the words, returning just the ones that are <= 3 characters in length
return this.spanishWords.filter(word => word.length <= 3);
}
}
<h2>Short Spanish words:</h2>
<ul>
<li v-for='thisWord in shortSpanishWords'>{{ thisWord }}</li>
</ul>
Watchers
Another feature Vue.js provides is the ability to set a watcher on a data property.
Watchers, like computed properties, allow you to dynamically update properties but it requires a more imperative and verbose style. Here's our “full name” example from above, revisited with watchers instead of a computed property:
const Example = {
data() {
return {
firstName: '',
lastName: '',
fullName: '',
}
},
watch: {
// When firstName changes, this function is invoked
firstName(val) {
this.fullName = val + ' ' + this.lastName;
},
// When lastName changes, this function is invoked
lastName(val) {
this.fullName = this.firstName + ' ' + val;
}
}
}
In the above example, we imperatively made fullName
act like a computed property by setting a watcher on firstName
and lastName
.
In this example, computed properties are clearly the best solution.
However, there are times when watchers
are the right tool for the job such as when you want to perform some action as the result of a property changing.
Methods vs. Computed Properties vs. Watchers
- Methods: React to an event happening in the DOM (e.g. a mouse click)
- Computed properties: Reactively compose data based on changes to other data
- Watchers: React with some action to a property changing