@@ -58,26 +58,56 @@ export default {
5858 return result
5959 }
6060
61+ function firstPrepare ( ) {
62+ prepare . call ( this )
63+ Object . defineProperty ( this , '$subReady' , {
64+ get : ( ) => this . $data . $meteor . subs ,
65+ enumerable : true ,
66+ configurable : true ,
67+ } )
68+ proxyData . call ( this )
69+ }
70+
6171 function prepare ( ) {
6272 this . _trackerHandles = [ ]
6373 this . _subsAutorun = { }
6474 this . _subs = { }
75+ }
76+
77+ function proxyData ( ) {
78+ const initData = this . $_meteorInitData = { }
79+ let meteor = this . $options . meteor
6580
66- // First launch
67- if ( this . _meteorLaunch == null ) {
68- this . _meteorLaunch = 0
81+ if ( meteor ) {
82+ // Reactive data
83+ for ( let key in meteor ) {
84+ if ( key . charAt ( 0 ) !== '$' ) {
85+ proxyKey . call ( this , key )
86+
87+ const func = meteor [ key ]
88+
89+ if ( meteor . $lazy && typeof func === 'function' ) {
90+ initData [ key ] = getResult ( func . call ( this ) )
91+ }
92+ }
93+ }
94+ }
95+ }
6996
70- Object . defineProperty ( this , '$subReady' , {
71- get : ( ) => this . $data . $meteor . subs ,
72- enumerable : true ,
73- configurable : true ,
74- } )
97+ function proxyKey ( key ) {
98+ if ( hasProperty ( this , key ) ) {
99+ throw Error ( `Meteor data '${ key } ': Property already used in the component methods or prototype.` )
75100 }
101+
102+ Object . defineProperty ( this , key , {
103+ get : ( ) => this . $data . $meteor . data [ key ] ,
104+ enumerable : true ,
105+ configurable : true ,
106+ } )
76107 }
77108
78109 function launch ( ) {
79110 this . _meteorActive = true
80- this . _meteorLaunch ++
81111
82112 let meteor = this . $options . meteor
83113
@@ -109,18 +139,18 @@ export default {
109139 data ( ) {
110140 return {
111141 $meteor : {
112- data : { } ,
142+ data : this . $_meteorInitData ,
113143 subs : { } ,
114144 } ,
115145 }
116146 } ,
117147
118148 ...vueVersion === '1' ? {
119- init : prepare ,
149+ init : firstPrepare ,
120150 } : { } ,
121151
122152 ...vueVersion === '2' ? {
123- beforeCreate : prepare ,
153+ beforeCreate : firstPrepare ,
124154 } : { } ,
125155
126156 created ( ) {
@@ -234,22 +264,20 @@ export default {
234264 this . _meteorActive = false
235265 } ,
236266
237- $addMeteorData ( key , func ) {
267+ $addMeteorData ( key , func , proxy = false ) {
238268 if ( typeof func === 'function' ) {
239269 func = func . bind ( this )
240270 } else {
241271 throw Error ( `Meteor data '${ key } ': You must provide a function which returns the result.` )
242272 }
243273
244- if ( hasProperty ( this . $data , key ) || hasProperty ( this . $props , key ) || ( hasProperty ( this , key ) && this . _meteorLaunch === 1 ) ) {
245- throw Error ( `Meteor data '${ key } ': Property already used in the component data, props or other.` )
246- }
274+ if ( proxy ) {
275+ if ( hasProperty ( this . $data , key ) || hasProperty ( this . $props , key ) ) {
276+ throw Error ( `Meteor data '${ key } ': Property already used in the component data or props.` )
277+ }
247278
248- Object . defineProperty ( this , key , {
249- get : ( ) => this . $data . $meteor . data [ key ] ,
250- enumerable : true ,
251- configurable : true ,
252- } )
279+ proxyKey . call ( this , key )
280+ }
253281
254282 // Function run
255283 const setResult = result => {
@@ -282,6 +310,7 @@ export default {
282310 } ,
283311
284312 $addComputed ( key , watcher ) {
313+ if ( watcher . getter . vuex ) return
285314 let computation , autorunMethod
286315 const autorun = ( cb ) => {
287316 if ( ! computation ) {
@@ -290,7 +319,20 @@ export default {
290319 computation = autorunMethod ( computation => {
291320 dirty = true
292321 watcher . value = getResult ( cb . call ( this ) )
293- watcher . deps . forEach ( dep => dep . notify ( ) )
322+ // Call watcher callback
323+ const get = watcher . get
324+ watcher . get = ( ) => watcher . value
325+ watcher . run ( )
326+ watcher . get = get
327+ // Notify watchers subscribed in dependencies
328+ for ( const dep of watcher . deps ) {
329+ const subs = dep . subs . slice ( )
330+ for ( const sub of subs ) {
331+ if ( sub . id !== watcher . id ) {
332+ sub . update ( )
333+ }
334+ }
335+ }
294336 dirty = false
295337 } )
296338 // Update from Vue (override)
@@ -303,14 +345,20 @@ export default {
303345 return watcher . value
304346 }
305347 // Override getter to expose $autorun
306- const func = watcher . getter
348+ const getter = watcher . getter
307349 watcher . getter = ( ) => {
308350 autorunMethod = this . $autorun
309351 this . $autorun = autorun
310- const result = func . call ( this , this )
352+ const result = getter . call ( this , this )
311353 this . $autorun = autorunMethod
312354 return result
313355 }
356+ // If watcher was created before the computed property
357+ // (for example because of a $watch)
358+ // we update the result with the getter override
359+ if ( watcher . value instanceof Tracker . Computation ) {
360+ watcher . run ( )
361+ }
314362 } ,
315363 } ,
316364 } )
0 commit comments