@@ -58,26 +58,56 @@ export default {
58
58
return result
59
59
}
60
60
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
+
61
71
function prepare ( ) {
62
72
this . _trackerHandles = [ ]
63
73
this . _subsAutorun = { }
64
74
this . _subs = { }
75
+ }
76
+
77
+ function proxyData ( ) {
78
+ const initData = this . $_meteorInitData = { }
79
+ let meteor = this . $options . meteor
65
80
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
+ }
69
96
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.` )
75
100
}
101
+
102
+ Object . defineProperty ( this , key , {
103
+ get : ( ) => this . $data . $meteor . data [ key ] ,
104
+ enumerable : true ,
105
+ configurable : true ,
106
+ } )
76
107
}
77
108
78
109
function launch ( ) {
79
110
this . _meteorActive = true
80
- this . _meteorLaunch ++
81
111
82
112
let meteor = this . $options . meteor
83
113
@@ -109,18 +139,18 @@ export default {
109
139
data ( ) {
110
140
return {
111
141
$meteor : {
112
- data : { } ,
142
+ data : this . $_meteorInitData ,
113
143
subs : { } ,
114
144
} ,
115
145
}
116
146
} ,
117
147
118
148
...vueVersion === '1' ? {
119
- init : prepare ,
149
+ init : firstPrepare ,
120
150
} : { } ,
121
151
122
152
...vueVersion === '2' ? {
123
- beforeCreate : prepare ,
153
+ beforeCreate : firstPrepare ,
124
154
} : { } ,
125
155
126
156
created ( ) {
@@ -234,22 +264,20 @@ export default {
234
264
this . _meteorActive = false
235
265
} ,
236
266
237
- $addMeteorData ( key , func ) {
267
+ $addMeteorData ( key , func , proxy = false ) {
238
268
if ( typeof func === 'function' ) {
239
269
func = func . bind ( this )
240
270
} else {
241
271
throw Error ( `Meteor data '${ key } ': You must provide a function which returns the result.` )
242
272
}
243
273
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
+ }
247
278
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
+ }
253
281
254
282
// Function run
255
283
const setResult = result => {
@@ -282,6 +310,7 @@ export default {
282
310
} ,
283
311
284
312
$addComputed ( key , watcher ) {
313
+ if ( watcher . getter . vuex ) return
285
314
let computation , autorunMethod
286
315
const autorun = ( cb ) => {
287
316
if ( ! computation ) {
@@ -290,7 +319,20 @@ export default {
290
319
computation = autorunMethod ( computation => {
291
320
dirty = true
292
321
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
+ }
294
336
dirty = false
295
337
} )
296
338
// Update from Vue (override)
@@ -303,14 +345,20 @@ export default {
303
345
return watcher . value
304
346
}
305
347
// Override getter to expose $autorun
306
- const func = watcher . getter
348
+ const getter = watcher . getter
307
349
watcher . getter = ( ) => {
308
350
autorunMethod = this . $autorun
309
351
this . $autorun = autorun
310
- const result = func . call ( this , this )
352
+ const result = getter . call ( this , this )
311
353
this . $autorun = autorunMethod
312
354
return result
313
355
}
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
+ }
314
362
} ,
315
363
} ,
316
364
} )
0 commit comments