vue: Interesting bug / quirk computed property not updating correctly, but probably not fixable
Hi consider this snippet:
...
computed: {
someProp() {
if(this.nonReactiveProperty) {
return this.reactiveProperty;
}
}
},
...
From the documentation I would assume (please show me if I missed something) that someProp() should get re-evaluated when this.reactiveProperty does change. Works as expected as long as this.nonReactiveProprty is true all time. However, if this.nonReactiveProperty is false the first time someProp() is read, then someProp() will never re-evaluate, even if this.reactiveProperty changes (after this.nonReactiveProperty gets true).
The problem is, I guess it is not fixable. Am I assuming correctly, that the dependencies of someProp() get calculated the first time it is executed? So code which does not get executed then, vue is just blind of…?
This is quite tricky and probably I’ve run into this quite some times before figuring out. It gets even harder to see when inside lazy conditions. E.g. this works all the time:
someProp() {
if(this.reactiveProperty && this.nonReactiveProperty) {
return this.reactiveProperty;
}
}
while this might not:
someProp() {
if(this.nonReactiveProperty && this.reactiveProperty) {
return this.reactiveProperty;
}
}
So if this is not fixable, and I didn’t miss something, I would suggest to add this to the documentation.
EDIT: here is a codesandbox: https://codesandbox.io/s/priceless-leftpad-kktuq?file=/src/App.vue
best Martin
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 15 (3 by maintainers)
@derMart
EDIT: Nvm, noticed you mentioned that in the last reply. 😅 I think that behaviour could be better described in the API docs.
It’s worth adding that (as far as I remember) the dependencies are collected whenever the computed property executes without using the cache. Any dependencies collected during previous runs will also be removed.
So in case you have several conditionals:
When
this.reactiveProp === 0istrue, the only dependencies collected will be:this.reactivePropandthis.anotherReactiveProp. Whenthis.reactiveProp === 0isfalseandthis.yetAnotherReactiveProp === 1is true, the collected dependencies list will be:this.reactivePropandthis.yetAnotherReactiveProp. When neither of those two conditions pass (finalelsereturns), the list of dependencies will look like this:this.reactiveProp,this.yetAnotherReactivePropandthis.alsoReactiveProp.As you can see the list of dependencies is dynamic and collected at runtime as it was already mentioned. Which means if during the last execution of that computed property something wasn’t registered as a dependency, changing it won’t trigger a recalculation. And this is ultimately a good thing if you think about it.