-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make computed property caching optional #1189
Comments
Please provide a reproduction where it doesn't work as intended. |
Consider the following, a paginated list that can have multiple columns. function entitiesPerViewport () {
// The paginated list is a child of a scrollable container.
var clientHeight = this.$parent.$el.clientHeight;
return this.columns * Math.round(clientHeight / this.entityHeight);
}; Prior to the change in computed property evaluation, this always worked. Now it must be placed in
but offer no explanation to the conditions that invalidate the cache. I suspect that only changes to tracked |
Hmm, I guess this is because I personally only use computed properties for making the view declarative - i.e. I bind to it in the template, but never rely on it in imperative code. It was never meant to be used as a getter, but I guess a lot of people do. @TeffenEllis you are right that the cache only invalidates when a reactive dependency has changed. Vue has no way of knowing when an external dependency like I can make the cache optional, since it only makes a performance difference when the computed property is unusually expensive. |
I believe that adding a config to making computed property cache optional might be unnecessary. Clarification in the documentation can help the user understand when a computed property is appropriate over a getter function.
Thank you! |
@TeffenEllis It could be done in a very unobtrusive way. By default it will work like before (without caching). If you really need caching for some specific scenario, you can enable it on a per-property basis: computed: {
a: function () {
// getter-like computed
},
b: {
cache: true,
get: function () {
// cached, only re-evaluates when a reactive dependency changes
}
}
} |
+1 on a per computed configuration, defaulting to |
@yyx990803 computed: {
a: function () {
// getter-like computed
},
b: {
cache: function() {
//check if the property is outdated
},
get: function () {
// cached, only re-evaluates when a reactive dependency changes
}
}
} Plus, boolean |
@karevn I don't really see the point for making |
@yyx990803 the "hard" way with the |
I think making |
If most of computed properties are only evaluated once - what is the point of having them at all? It's easier to just make one computation at |
@karevn I don't think you really understand what computed properties are for. It's not a "automagic always up-to-date" property - it's used to compute value based on other reactive values. If you are putting a lot of window/DOM sizes inside computed properties and expect them to act as dependencies, I'd say you are using it wrong, and that's why you find it "not useful". |
@yyx990803 Got it. But... if all the computations are based on vue's reactive values only, then they're pretty cheap, and why bother with caching them at all? |
@karevn it's cheap most of the time, but you can also, say, have a computed property that map/filter/reduces a HUGE array, which can be slow. Then let's suppose you have additional computed properties that rely on this one... you'd be calling the expensive computed property many more times than necessary. |
@yyx990803 Agree. But... I still think adding more control over caching will not hurt. :) |
@yyx990803 I meant function value for |
@karevn but that would not be very useful, because how do we know when to call that function? If we only call it when a reactive dependency changes, then it's not really different from cached. |
Was this implemented in Vue 2.0? My computed properties aren't updating when a shared store is updated. Computed properties are needed for v-model attribute. In my situation, the shared store contains the root node (render pipeline manager) which render function creates new elements passing the previous element in the pipeline in as a slot (essentially nested components all referencing the same store for their property). The computed property that is referenced in a "v-model" attribute updates the root node's data via the store. This then trickles down the render pipeline exactly as expected, however, the computed properties in all child nodes remain as the same value. Not sure if this is a bug in Vue or a good use case for computed property cache busting. Update: This issue also exists for the root node's computed properties, made those into methods to avoid this issue, however, the child nodes still rely on the computed property as described above. |
@adrianb93 this was later reverted. Caching is now enabled by default for computed properties. The behavior you are describing is mostly like because your shared store isn't made reactive, but your description is still to vague to determine the real cause. If you think it's a bug you should be opening a separate issue with proper reproduction. |
@yyx990803 |
@mesqueeb please, don't ask question on issues, even less on closed ones. Use the Forum instead. You can use a method (https://vuejs.org/v2/guide/migration.html#cache-false-deprecated) |
@adrianb93 Have you solved your problem? I think I may be facing the same problem. When I use a single Store, the computed properties are reactive to the Store's getters and when I use the Store as a module, it is not reactive any longer. I have been stuck on this for a few days. |
For some reason my computed properties that are based on Vuex state are not cached. Im not using a Vuex getter that is a function, so it should be cached. But it is being called all the time. Look at the code below. There are two dependencies in the computed: {
...mapState({
defaultApiVersion: (state) => state.salesforce.defaultApiVersion,
salesforceApiVersions: (state) => state.salesforce.apiVersions
}),
state(){
return this.$store.state[this.editorName]
},
apiVersions(){
return this.salesforceApiVersions[this.username] ? this.salesforceApiVersions[this.username]
.map((apiVersion) => {
return 'v' + apiVersion.version
}) : []
},
}, |
"computed" properties were re-calculated on any change in past. Now, they're cached, and the algorithm used does not make sense for me (and most of other people, I'm sure). At least, it never flushed and updated computed properties in my project, being actually useless. So, I think having a good documentation or flush algorithm that would match "common sense" is a must for this feature.
The text was updated successfully, but these errors were encountered: