Methods, Computed, and Watchers in Vue.js
One of the reasons I love working with Vue is because of how useful methods
, computed
, and watchers
are, and the legibility of their distinction. Until understanding all three, it’s difficult to leverage the functionality of Vue to its full potential. Still, the majority of people I see confused about this framework tend to also be confused about the differences here, so let’s dig in.
In case you need a quick answer and don’t have time to read through the entire article, here’s a small TL;DR:
- Methods: These are exactly what they sound like they might be (yay, naming!). They’re functions that hang off of an object—typically the Vue instance itself or a Vue component.
-
Computed: These properties may at first look like they’d be used like a method, but are not. In Vue, we use
data
to track changes to a particular property that we’d like to be reactive. Computed properties allow us to define a property that is used the same way asdata
, but can also have some custom logic that is cached based on its dependencies. You can consider computed properties another view into your data. - Watchers: These are allowing you a peek into the reactivity system. We’re offered some hooks with which to observe any properties that are stored by Vue. If we want to add a bit of functionality each time something changes, or respond to a particular change, we could watch a property and apply some logic. This means that the name of the watcher has to match what we’re trying to observe.
If any of this sounds confusing, don’t worry! We’ll dive in further below and hopefully address any confusion. If you’re familiar with vanilla JavaScript already, methods may be pretty obvious to you, aside from one or two caveats. It might then behoove you (I love that phrase) to skip to the Computed and Watchers sections.
Computed
Computed properties are very valuable for manipulating data that already exists. Anytime you’re building something where you need to sort through a large group of data and you don’t want to rerun those calculations on every keystroke, think about using a computed value.
Some good candidates include, but are not limited to:
- Updating a large amount of information while a user is typing, such as filtering a list
- Gathering information from your Vuex store
- Form validation
- Data visualizations that change depending on what the user needs to see
Computed properties are a vital part of Vue to understand. They are calculations that will be cached based on their dependencies and will only update when needed. They’re extremely performant when used well and extraordinarily useful. There are many large libraries that handle this kind of logic that you can now eliminate with only a few lines of code.
Computed properties aren’t used like methods, though at first, they might look similar- you’re stating some logic in a function and returning- but the name of that function becomes a property that you’d then use in your application like data
.
If we needed to filter this big list of names of heroes based on what the user was typing, here’s how we would do it. We’re keeping this really simple so you can get the base concepts down. Originally our list would output in our template using names
, which we store in data
:
new Vue({ el: ‘#app‘, data() { return { names: [ ‘Evan You‘, ‘John Lindquist‘, ‘Jen Looper‘, ‘Miriam Suzanne‘, ... ] } } })
<div id="app"> <h1>Heroes</h1> <ul> <li v-for="name in names"> {{ name }} </li> </ul> </div>
Now let’s create a filter for those names. We’ll start by creating an input with v-model
that will originally be an empty string, but we’ll eventually use to match and filter through our list. We’ll call this property findName
and you can see it referenced both on the input and in the data
.
<label for="filtername">Find your hero:</label>
<input v-model="findName" id="filtername" type="text" />
data() {
return {
findName: ‘‘,
names: [
‘Evan You‘,
‘John Lindquist‘,
...
]
}
}
Now, we can create the computed property that will filter all of the names based on what the user has typed into the input, so anything in our findName
property. You’ll note that I’m using regex here to make sure that mismatched capitalization doesn’t matter, as users will typically not capitalize as they type.
computed: {
filteredNames() {
let filter = new RegExp(this.findName, ‘i‘)
return this.names.filter(el => el.match(filter))
}
}
And now we’ll update what we’re using in the template to output from this:
<ul>
<li v-for="name in names">
{{ name }}
</li>
</ul>
…to this:
<ul>
<li v-for="name in filteredNames">
{{ name }}
</li>
</ul>
And it filters for us on every keystroke! We only had to add a couple of lines of code to make this work, and didn’t have to load any additional libraries.
I can’t tell you how much time I save by using them. If you’re using Vue and haven’t explored them yet, please do, you’ll thank yourself.