Impossible to create a getter on app.config.globalProperties
What problem does this feature solve?
In Vue 2 I had a getter defined as Vue.prototype.$app
– this wasn’t a static value but rather computed for each component (walking up the parents chain until the right component was located). Doing the same with Vue 3 turned out impossible: getters on app.config.globalProperties
aren’t transferred to the instance. Instead, they are resolved with app.config.globalProperties
as this
.
What does the proposed API look like?
Maybe the code behind processing app.config.globalProperties
should recognize getters and setters, calling them appropriately when proxy handler’s get()
and set()
methods are called.
In what way? Define a created()
method and set a property there? Sounds like a rather wasteful and non-straightforward approach.
Note that personally I’m not looking for a work-around, I solved this in another way already. That’s a capability which was present in Vue 2 however and makes migration harder.
Vue components don't have a prototype anymore.
We could kind of replicate the behavior with something like this inserted here:
else if (hasOwnProperty(globalProperties, key)) {
const descriptor = Object.getOwnPropertyDescriptor(globalProperties, key)
if (descriptor.get) {
return descriptor.get.call(instance.proxy)
} else {
return globalProperties[key]
}
}
and likewise we would likely adjust the behavior when trying to set a property that exists in globalProperties, but has a setter?
I'm personally torn - does this overcomplicates the behavior of globalProperties
that is right now just a simple object, or is the use case mentioned by @palant worth it?
Because extending a prototype with a getter makes it clear that you will have access to the in instance created from that prototype through this
in the getter - that's just plain JS. The hack that I fleshed out above would have to be documented and explained as it's not apparent why a getter on that plain would give you access to the component instance through this
.
Such a getter would definitely be cheaper than a global mixin that adds a property to each instance, but would it actually have a measurable impact?
I did something similar in some of my Vue 2 applications. I needed access to this
and didn't want to add any extra overhead to components that didn't use the property. A getter on Vue.prototype
worked perfectly.
So far I've only migrated one, very small application to Vue 3. I switched it to use a global mixin with a computed
property instead. That did work in that case but the application was far too small to assess the performance impact.
I've worked on large applications (a long time ago, pre-Vue) where performance became a major problem because of several, very small inefficiencies. That experience has always made me very wary of features like global mixins.
If it were possible to use a getter with globalProperties
I would definitely have used that instead.
Hi there,
Any news on this issue ? I'm in the same situation, I need to use a getter for a globalPropertie but it seems there's no way to do that ?
If you need to define a dynamic global property, for example, a $store
per Storybook story, try this.
app.mixin({
beforeCreate() {
this.$store = $store
}
})
It works because Vue3 allows defining $xxx properties in VM. However, an attempt to define $store
as a computed property would fail.