I've been using Vue for a while, and my experience has always been a method will recompute if its underlying reactive data is updated. I've encountered conflicting information on SO:
I searched through the docs and I didn't see anything incredibly clear.
If they are not reactive, then why does this example work?
<ul>
<li v-for="animal in animals" :key="animal.id">
<span v-if="isAwesome(animal)">{{ animal.name }}</span>
</li>
</ul>
export default {
data() {
return {
awesomeAnimalIds: [],
animals: [
{ id: 1, name: 'dog' },
{ id: 5, name: 'cat' },
{ id: 9, name: 'fish' },
],
};
},
created() {
setTimeout(() => {
this.awesomeAnimalIds.push(5);
}, 1000);
setTimeout(() => {
this.awesomeAnimalIds.push(9);
}, 2000);
},
methods: {
isAwesome(animal) {
return this.awesomeAnimalIds.includes(animal.id);
},
},
};
I would really like to have a definitive and satisfying answer that this community can refer to.
Based on How Changes Are Tracked from the docs, here's what's going on:
A special watcher is created for the component instance to determine when a re-render is required.
Vue converts all properties of data
to getters and setters.
get animals() {
// Add dependency: potentially trigger a re-render if animals updates
...
}
set animals() {
// Notify the watcher that animals has been updated
...
}
get awesomeAnimalIds() {
// Add dependency: potentially trigger a re-render if awesomeAnimalIds updates
...
}
set awesomeAnimalIds() {
// Notify the watcher that awesomeAnimalIds has been updated
...
}
isAwesome
is made from the template.isAwesome
, the getter for awesomeAnimalIds
is invoked.awesomeAnimalIds
field of data
.awesomeAnimalIds
is updated, which invokes the awesomeAnimalIds
setter.data
field which received a notification, a re-render is triggered.From this and the example above, we can conclude the following:
A method call made from a template establishes a reactive dependency on the subset of
data
fields used in the method call stack. If the underlying fields are updated, it will trigger a re-render of the component.
There is a common misconception that methods are "invoked only once" or "fire and forget" when called from a template. This is clearly not always the case because methods can establish a reactive dependency.
So when should we use a computed property vs a method?
See the guide section on Computed Caching vs Methods. Here's my take on it:
fetch
from them.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With