Reputation: 7129
I am getting my head round the different ways of communicating between components and their children, grandchildren, etc., and have been taking a look at provide/inject for the first time. I can get this to work fine without being reactive (which I know is the way it is designed), but cannot get reactive behaviour using an observed object. Let's say I have a nested object structure, A > B > C, where A is the grandparent of C. I have a data property of A, 'page', changes to which I would like to observe in grandchild C. If I just provide 'page' in A and inject 'page' in C, it's not reactive (by design). I thought if I did something like this instead it might work:
In provider:
data() {
return {
page: null,
obj:{currentPage:this.page}
}
},
provide(){
return {
obj: this.obj
}
}
In child or grandchild:
inject: ['obj']
But it doesn't. If I try to use obj.currentPage in the grandchild component, it is undefined.
I'm sure this is pretty straightforward. What am I not getting?
Upvotes: 13
Views: 13663
Reputation: 608
I spent a lot of time, trying to make provided/injected object reactive, and after all it was eureka! We can simply pass a function returning an object, not an object themself.
It seems as a good solution to me.
Provider:
data(){
return {
something: ...,
}
}
provide(){
return {
getSomething: () => this.something,
}
}
Descedant component:
inject: ['getSomething'],
computed: {
something(){
return this.getSomething();
}
}
So, in descedant component, computed property this.something
became reactive.
Upvotes: 33
Reputation: 7129
Well, as ever the answer turned out to be in a completely different place from where I was looking. There is nothing wrong with the reactivity of the 'obj' object being provided. The problem lies in the fact that the object is not being updated in the parent data object. I had obj:{currentPage:this.page}
assuming that when this.page
changes, the property within obj
would be updated, but it isn't. So I have two options here, unless I've missed something: firstly, use a watch
on page
, updating the obj
property; or forget about this.page
altogether and make sure any updates which were hitherto done to this.page
are instead done to this.obj.currentPage
. It's just a case of deciding which approach is the less messy. All part of an interesting learning exercise.
Upvotes: 4