You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
One of the trickiest pitfalls with Vue reactivity is the fact that adding reactivity involves wrapping an object. The original object isn't reactive, only the wrapper created with new Vue({data: {...}}).
letoriginal={wow: 10};letreactive=newVue({data: original});original.wow=20;// this doesn't cause reactions
When using @VueStore this becomes a problem if you capture this in the constructor:
@VueStoreclassAsyncStore{value: string=nullconstructor(id){requestData(id).then((v)=>{this.value=v;// the captured `this` refers to the original, not the reactive wrapper});}}
Proposal
It would be great if we could inject reactivity into the original object, that way the captured this would be reactive. #27 is my implementation of this.
Implementation
The principle behind my solution is double-initializing the object. After the store is constructed we rip out the data, then we turn around and ask Vue to initialize this now-empty object with the extracted data.
In order to do this we have to extend Vue while not extending the Vue constructor. If we extended the constructor, Vue would initialize the object before we get a chance to add our data.
Details
The way I implement this quasi-inheritance is that, instead of having Vue in the prototype chain, I literally copy the contents of the Vue prototype into the store's prototype.
The double-initialization is feasible because the Vue constructor just calls this._init(options). Because we copied the prototype, all we have to do is take the initialized store, rip out the data, then call store._init({data: extractedData}).
It might be worth emulating the Vue 3 API limitations with regard to inheritance. i.e. we could require you subclass VueStore to get the new this safety, to ease the transition to Vue 3.
The text was updated successfully, but these errors were encountered:
Background
One of the trickiest pitfalls with Vue reactivity is the fact that adding reactivity involves wrapping an object. The original object isn't reactive, only the wrapper created with
new Vue({data: {...}})
.When using
@VueStore
this becomes a problem if you capturethis
in the constructor:Proposal
It would be great if we could inject reactivity into the original object, that way the captured
this
would be reactive. #27 is my implementation of this.Implementation
The principle behind my solution is double-initializing the object. After the store is constructed we rip out the data, then we turn around and ask Vue to initialize this now-empty object with the extracted data.
In order to do this we have to extend
Vue
while not extending theVue
constructor. If we extended the constructor, Vue would initialize the object before we get a chance to add our data.Details
The way I implement this quasi-inheritance is that, instead of having Vue in the prototype chain, I literally copy the contents of the
Vue
prototype into the store's prototype.The double-initialization is feasible because the Vue constructor just calls
this._init(options)
. Because we copied the prototype, all we have to do is take the initialized store, rip out the data, then callstore._init({data: extractedData})
.Vue 3
See #29
It might be worth emulating the Vue 3 API limitations with regard to inheritance. i.e. we could require you subclass
VueStore
to get the newthis
safety, to ease the transition to Vue 3.The text was updated successfully, but these errors were encountered: