2.5.3
https://codesandbox.io/s/7o2qp4l3z6
Parent Component
provide() {
let reactive = {};
Object.defineProperties(reactive, {
challenge: {
get: () => this.challenge
}
});
return reactive;
},
Child Component
inject: ["challenge"]
The challenge property should change when its parent this.challenge changes on the proxy
Not changing at all
The link provided is just an example how to reimplement what i'm really doing but that is the same code that i use
any ideas?
Unfortunately, that's by design. you can hack around it using an object an referring to its children, but it's not recommended because it could break in future versions of Vue
I'd like to point out two possible solutions to this problem:
// parent:
{
provide() {
return {
$computedProperty: () => this.computedProperty
}
},
computed: {
computedProperty() {
// Returns the result of some potentially reactive computation
}
}
}
// children:
{
inject: [
'$computedProperty'
],
computed: {
computedProperty() {
return this.$computedProperty()
}
聽聽}
}
That second trick is great, never thought of that!
@LinusBorg a function used as a tunnel / wormhole through the non-reactive JS space-continuum :)
@lehni
Just a small mistake, this
is not accessible within the provide
object you need to declare it like this for it to work
provide() {
return {
$computedProperty: () => this.computedProperty,
};
},
@Tofandel hmmm but you have the same code there as I do? And I'm using this in production, sure works for me...
@Tofandel never mind, I just noticed now that @posva edited my code to include your fix before I saw your post. I also have this version in my own use, not sure why I posted the object version above initially :)
@lehni Haha okay I thought you edited it so I was confused :p
This must be added to the recipes or guides.
I have discovered new way:
// parent:
{
provide() {
const _this = this;
return {
get computedProperty () {
return _this.computedProperty;
}
}
},
computed: {
computedProperty() {
// Returns the result of some potentially reactive computation
}
}
}
// children:
{
inject: [
'computedProperty'
],
}
You don't need computed method in children anymore.
I discovered a flaw in @lehni 's trick today. Wrapping the object in a function triggers an error when the providing object gets unmounted I think, as if the injection briefly couldn't be resolved anymore:
[Vue warn]: Injection "$computedProperty" not found
This error doesn't happen when a plain object is passed.
I could circumvent it by providing a wrapped-wrapped (!) default value in the child component:
// children:
{
inject: [
'$computedProperty': {
// you need to provide a default object that doesn't trigger errors
// in your component when used
default: () => () => {}
}
],
computed: {
computedProperty() {
return this.$computedProperty()
}
}
}
It feels dirty overall. We should probably avoid passing functions.
As a reminder, the Vue docs advise against inject/provide anyway, and just use props, even if it's more verbose.
@cihad I haven't been able to make your trick work, it's not reactive for me. And I needed two different names to avoid a loop: get computedProperty () { return _this.$computedProperty
}
It seems like the only way to get it to work is by providing
a function, and then in the component it is injected in you need to create a computed prop and call the function like the example above.
Has there been any progress on opinions of how to tackle this? I dont want to prop drill or use state management. Provide/Inject seems like the best solution, but feels weird we need to hack around the cleanest solution.
Thoughts?
Most helpful comment
I'd like to point out two possible solutions to this problem: