1
- import Vue from 'weex/runtime/index'
2
- import renderer from 'weex/runtime/config'
1
+ import TextNode from 'weex/runtime/text-node'
3
2
4
- Vue . weexVersion = '__WEEX_VERSION__'
5
- export { Vue }
3
+ // this will be preserved during build
4
+ const VueFactory = require ( './factory' )
6
5
7
- const {
6
+ const instances = { }
7
+ const modules = { }
8
+ const components = { }
9
+
10
+ const renderer = {
11
+ TextNode,
8
12
instances,
9
13
modules,
10
14
components
11
- } = renderer
12
-
13
- let activeId
14
- const oriIsReservedTag = ( Vue && Vue . config && typeof Vue . config . isReservedTag === 'function' ) ? Vue . config . isReservedTag : function ( ) { }
15
+ }
15
16
16
17
/**
17
18
* Prepare framework config, basically about the virtual-DOM and JS bridge.
@@ -35,7 +36,6 @@ export function reset () {
35
36
delete renderer . Element
36
37
delete renderer . Comment
37
38
delete renderer . sendTasks
38
- Vue . config . isReservedTag = oriIsReservedTag
39
39
}
40
40
41
41
/**
@@ -63,9 +63,6 @@ export function createInstance (
63
63
data ,
64
64
env = { }
65
65
) {
66
- // Set active instance id and put some information into `instances` map.
67
- activeId = instanceId
68
-
69
66
// Virtual-DOM object.
70
67
const document = new renderer . Document ( instanceId , config . bundleUrl )
71
68
@@ -78,7 +75,7 @@ export function createInstance (
78
75
// The latest callback id, incremental.
79
76
const callbackId = 1
80
77
81
- instances [ instanceId ] = {
78
+ const instance = instances [ instanceId ] = {
82
79
instanceId, config, data,
83
80
document, callbacks, callbackId
84
81
}
@@ -95,26 +92,13 @@ export function createInstance (
95
92
}
96
93
Object . freeze ( weexInstanceVar )
97
94
98
- // Each instance has a independent `Vue` variable and it should have
99
- // all top-level public APIs.
100
- const subVue = Vue . extend ( { } )
101
-
102
- // ensure plain-object components are extended from the subVue
103
- subVue . options . _base = subVue
104
-
105
- // expose global utility
106
- ; [ 'util' , 'set' , 'delete' , 'nextTick' , 'version' , 'weexVersion' , 'config' ] . forEach ( name => {
107
- subVue [ name ] = Vue [ name ]
108
- } )
109
-
110
- // expose weex native module getter on subVue prototype so that
111
- // vdom runtime modules can access native modules via vnode.context
112
- subVue . prototype . _requireWeexModule = moduleGetter
95
+ // Each instance has a independent `Vue` mdoule instance
96
+ const Vue = instance . Vue = createVueModuleInstance ( instanceId , moduleGetter )
113
97
114
98
// The function which create a closure the JS Bundle will run in.
115
99
// It will declare some instance variables like `Vue`, HTML5 Timer APIs etc.
116
100
const instanceVars = Object . assign ( {
117
- Vue : subVue ,
101
+ Vue,
118
102
weex : weexInstanceVar ,
119
103
__weex_require_module__ : weexInstanceVar . requireModule // deprecated
120
104
} , timerAPIs )
@@ -131,7 +115,7 @@ export function createInstance (
131
115
*/
132
116
export function destroyInstance ( instanceId ) {
133
117
const instance = instances [ instanceId ] || { }
134
- if ( instance . app instanceof Vue ) {
118
+ if ( instance . app instanceof instance . Vue ) {
135
119
instance . app . $destroy ( )
136
120
}
137
121
delete instances [ instanceId ]
@@ -146,11 +130,11 @@ export function destroyInstance (instanceId) {
146
130
*/
147
131
export function refreshInstance ( instanceId , data ) {
148
132
const instance = instances [ instanceId ] || { }
149
- if ( ! ( instance . app instanceof Vue ) ) {
133
+ if ( ! ( instance . app instanceof instance . Vue ) ) {
150
134
return new Error ( `refreshInstance: instance ${ instanceId } not found!` )
151
135
}
152
136
for ( const key in data ) {
153
- Vue . set ( instance . app , key , data [ key ] )
137
+ instance . Vue . set ( instance . app , key , data [ key ] )
154
138
}
155
139
// Finally `refreshFinish` signal needed.
156
140
renderer . sendTasks ( instanceId + '' , [ { module : 'dom' , method : 'refreshFinish' , args : [ ] } ] , - 1 )
@@ -162,7 +146,7 @@ export function refreshInstance (instanceId, data) {
162
146
*/
163
147
export function getRoot ( instanceId ) {
164
148
const instance = instances [ instanceId ] || { }
165
- if ( ! ( instance . app instanceof Vue ) ) {
149
+ if ( ! ( instance . app instanceof instance . Vue ) ) {
166
150
return new Error ( `getRoot: instance ${ instanceId } not found!` )
167
151
}
168
152
return instance . app . $el . toJSON ( )
@@ -177,7 +161,7 @@ export function getRoot (instanceId) {
177
161
*/
178
162
export function receiveTasks ( instanceId , tasks ) {
179
163
const instance = instances [ instanceId ] || { }
180
- if ( ! ( instance . app instanceof Vue ) ) {
164
+ if ( ! ( instance . app instanceof instance . Vue ) ) {
181
165
return new Error ( `receiveTasks: instance ${ instanceId } not found!` )
182
166
}
183
167
const { callbacks, document } = instance
@@ -229,68 +213,75 @@ export function registerModules (newModules) {
229
213
* @param {array } newComponents
230
214
*/
231
215
export function registerComponents ( newComponents ) {
232
- const config = Vue . config
233
- const newConfig = { }
234
216
if ( Array . isArray ( newComponents ) ) {
235
217
newComponents . forEach ( component => {
236
218
if ( ! component ) {
237
219
return
238
220
}
239
221
if ( typeof component === 'string' ) {
240
222
components [ component ] = true
241
- newConfig [ component ] = true
242
223
} else if ( typeof component === 'object' && typeof component . type === 'string' ) {
243
224
components [ component . type ] = component
244
- newConfig [ component . type ] = true
245
225
}
246
226
} )
247
- const oldIsReservedTag = config . isReservedTag
248
- config . isReservedTag = name => {
249
- return newConfig [ name ] || oldIsReservedTag ( name )
250
- }
251
227
}
252
228
}
253
229
254
- // Hack `Vue` behavior to handle instance information and data
255
- // before root component created.
256
- Vue . mixin ( {
257
- beforeCreate ( ) {
258
- const options = this . $options
259
- const parentOptions = ( options . parent && options . parent . $options ) || { }
260
-
261
- // root component (vm)
262
- if ( options . el ) {
263
- // record instance info
264
- const instance = instances [ activeId ] || { }
265
- this . $instanceId = activeId
266
- options . instanceId = activeId
267
- this . $document = instance . document
268
-
269
- // set external data of instance
270
- const dataOption = options . data
271
- const internalData = ( typeof dataOption === 'function' ? dataOption ( ) : dataOption ) || { }
272
- options . data = Object . assign ( internalData , instance . data )
273
-
274
- // record instance by id
275
- instance . app = this
276
-
277
- activeId = undefined
278
- } else {
279
- this . $instanceId = options . instanceId = parentOptions . instanceId
280
- }
281
- }
282
- } )
283
-
284
230
/**
285
- * @deprecated Just instance variable `weex.config`
286
- * Get instance config.
287
- * @return {object }
231
+ * Create a fresh instance of Vue for each Weex instance.
288
232
*/
289
- Vue . prototype . $getConfig = function ( ) {
290
- const instance = instances [ this . $instanceId ] || { }
291
- if ( instance . app instanceof Vue ) {
292
- return instance . config
233
+ function createVueModuleInstance ( instanceId , moduleGetter ) {
234
+ const exports = { }
235
+ VueFactory ( exports , renderer )
236
+ const Vue = exports . Vue
237
+
238
+ const instance = instances [ instanceId ]
239
+
240
+ // patch reserved tag detection to account for dynamically registered
241
+ // components
242
+ const isReservedTag = Vue . config . isReservedTag || ( ( ) => false )
243
+ Vue . config . isReservedTag = name => {
244
+ return components [ name ] || isReservedTag ( name )
245
+ }
246
+
247
+ // expose weex-specific info
248
+ Vue . prototype . $instanceId = instanceId
249
+ Vue . prototype . $document = instance . document
250
+
251
+ // expose weex native module getter on subVue prototype so that
252
+ // vdom runtime modules can access native modules via vnode.context
253
+ Vue . prototype . $requireWeexModule = moduleGetter
254
+
255
+ // Hack `Vue` behavior to handle instance information and data
256
+ // before root component created.
257
+ Vue . mixin ( {
258
+ beforeCreate ( ) {
259
+ const options = this . $options
260
+ // root component (vm)
261
+ if ( options . el ) {
262
+ // set external data of instance
263
+ const dataOption = options . data
264
+ const internalData = ( typeof dataOption === 'function' ? dataOption ( ) : dataOption ) || { }
265
+ options . data = Object . assign ( internalData , instance . data )
266
+ // record instance by id
267
+ instance . app = this
268
+ }
269
+ }
270
+ } )
271
+
272
+ /**
273
+ * @deprecated Just instance variable `weex.config`
274
+ * Get instance config.
275
+ * @return {object }
276
+ */
277
+ Vue . prototype . $getConfig = function ( ) {
278
+ const instance = instances [ this . $instanceId ] || { }
279
+ if ( instance . app instanceof Vue ) {
280
+ return instance . config
281
+ }
293
282
}
283
+
284
+ return Vue
294
285
}
295
286
296
287
/**
0 commit comments