Reputation: 43
My understanding of computed properties is that if the computed property is not used in the template it's not supposed to be computed. However, when there is a watcher for a computed property, this computed property is evaluated.
I understand it's not desired application architecture, but my question is if the fact that it's working this way is a desired Vue behaviour or some side-effect of how things are implemented right now and can change in future releases?
Or to put the question in other words: Should the computed property be evaluated if it's not used in the template and it has no other explicit getter in the codebase, except a watcher?
Example:
<template>
<div>
<button @click="counter++">+1</button>
{{ counter }}
</div>
</template>
<script>
export default {
name: "Main",
data() {
return {
counter: 0,
};
},
computed: {
notUsedInTemplate() {
console.log("notUsedInTemplate computed called");
return this.counter + 1;
},
},
watch: {
notUsedInTemplate() {
console.log("notUsedInTemplate watch called");
},
},
};
</script>
Link to sandbox: https://codesandbox.io/s/computed-sandbox-ru3n3?file=/src/components/Main.vue:0-818
Upvotes: 1
Views: 2862
Reputation: 3036
You are right about the computed property. Anything in the computed property will attach to vue
instance and accessible in the template.
So, if it not used in template, it should not be in computed.
computed
properties are declarative in where as watch
is imperative.
computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
And the best part is that we’ve created this dependency relationship declaratively: the computed getter function has no side effects, which makes it easier to test and understand.
watch are functions that looks for changes and update the value.
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
By using computed getter property you are just making it easy for vue
to track the changes and update in a declarative way, however you can do the same wit watch
but it is imperative and vue need to look for changes and each changes required that function call to be trigger and later executing that function.
Upvotes: 0
Reputation: 37773
if the computed property is not used in the template it's not supposed to be computed
...is not correct. Correct statement is:
if the computed property is not used (anywhere) it's not supposed to be evaluated
Using watch
evaluates the property. In fact watch
is very similar to template re-rendering (In vue 3 re-rendering is in fact little special watchEffect)
Because to watch (anything):
notUsedInTemplate
getter - to find out what reactive data it is accessing (so this.counter
is tracked as dependency)this.counter
changes, watcher runs the notUsedInTemplate
getter again so it can compare new value to previous oneSo to answer the questions:
notUsedInTemplate
computed property but underlying data it uses to compute it's valueVue reactivity has always 2 phases:
See this chapter in the docs - How Changes Are Tracked - the example is explicitly mentioning only template re-rendering (which uses watcher created by Vue itself) but all of this applies to all watchers including those created by the user
Upvotes: 2