@mpxjs/core 2.9.66 → 2.9.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/global.d.ts +2 -0
- package/@types/index.d.ts +18 -2
- package/package.json +15 -7
- package/src/convertor/wxToReact.js +1 -1
- package/src/core/mergeOptions.js +1 -1
- package/src/core/proxy.js +69 -1
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +22 -22
- package/src/platform/createApp.ios.js +77 -26
- package/src/platform/createApp.js +3 -1
- package/src/platform/export/apiInject.js +68 -0
- package/src/platform/export/apiInject.web.js +1 -0
- package/src/platform/export/index.js +5 -0
- package/src/platform/export/index.web.js +3 -1
- package/src/platform/patch/ali/getDefaultOptions.js +16 -3
- package/src/platform/patch/builtInKeysMap.js +2 -0
- package/src/platform/patch/react/getDefaultOptions.ios.js +47 -33
- package/src/platform/patch/web/getDefaultOptions.js +4 -2
- package/src/platform/patch/wx/getDefaultOptions.js +9 -4
- package/src/runtime/createFactory.js +3 -0
- package/src/platform/builtInMixins/directiveHelperMixin.android.js +0 -2
- package/src/platform/builtInMixins/proxyEventMixin.android.js +0 -2
- package/src/platform/builtInMixins/refsMixin.android.js +0 -2
- package/src/platform/builtInMixins/styleHelperMixin.android.js +0 -2
- package/src/platform/createApp.android.js +0 -2
- package/src/platform/patch/react/getDefaultOptions.android.js +0 -1
package/@types/global.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ declare let __mpx_mode__: 'wx' | 'ali' | 'swan' | 'qq' | 'tt' | 'web' | 'dd' | '
|
|
|
4
4
|
// declaration for mpx env
|
|
5
5
|
declare let __mpx_env__: string
|
|
6
6
|
|
|
7
|
+
declare const Mixin: WechatMiniprogram.Behavior.Constructor
|
|
8
|
+
|
|
7
9
|
// Wildcard module declarations for ?resolve case
|
|
8
10
|
declare module '*?resolve' {
|
|
9
11
|
const resourcePath: string
|
package/@types/index.d.ts
CHANGED
|
@@ -137,6 +137,11 @@ interface ComponentOpt<D extends Data, P extends Properties, C, M extends Method
|
|
|
137
137
|
|
|
138
138
|
initData?: Record<string, any>
|
|
139
139
|
|
|
140
|
+
provide?: Record<string, any> | (() => Record<string, any>)
|
|
141
|
+
inject?:
|
|
142
|
+
| { [key: string]: string | Symbol | { from?: string | Symbol; default?: any } }
|
|
143
|
+
| Array<string>
|
|
144
|
+
|
|
140
145
|
[index: string]: any
|
|
141
146
|
}
|
|
142
147
|
|
|
@@ -259,13 +264,15 @@ interface MpxConfig {
|
|
|
259
264
|
ignoreWarning: boolean | string | RegExp | ((msg: string, location: string, e: Error) => boolean)
|
|
260
265
|
ignoreProxyWhiteList: Array<string>
|
|
261
266
|
observeClassInstance: boolean | Array<AnyConstructor>
|
|
262
|
-
errorHandler: (
|
|
267
|
+
errorHandler: (msg: String, location: String, e: Error) => any | null
|
|
268
|
+
warnHandler: (msg: String, location: String, e: Error) => any | null
|
|
263
269
|
proxyEventHandler: (e: WechatMiniprogram.CustomEvent) => any | null
|
|
264
270
|
setDataHandler: (data: object, target: ComponentIns<{}, {}, {}, {}, []>) => any | null
|
|
265
271
|
forceFlushSync: boolean,
|
|
266
272
|
webRouteConfig: object,
|
|
267
273
|
webConfig: object,
|
|
268
|
-
webviewConfig
|
|
274
|
+
webviewConfig: WebviewConfig,
|
|
275
|
+
rnConfig: object,
|
|
269
276
|
}
|
|
270
277
|
|
|
271
278
|
type SupportedMode = 'wx' | 'ali' | 'qq' | 'swan' | 'tt' | 'web' | 'qa'
|
|
@@ -306,6 +313,8 @@ export interface Mpx {
|
|
|
306
313
|
|
|
307
314
|
delete: typeof del
|
|
308
315
|
|
|
316
|
+
provide: typeof provide
|
|
317
|
+
|
|
309
318
|
config: MpxConfig
|
|
310
319
|
|
|
311
320
|
i18n: {
|
|
@@ -570,6 +579,13 @@ export function onScopeDispose (fn: () => void): void
|
|
|
570
579
|
export function set<T extends object> (target: T, key: string | number, value: any): void
|
|
571
580
|
export function del<T extends object> (target: T, key: keyof T): void
|
|
572
581
|
|
|
582
|
+
// provide & inject
|
|
583
|
+
export declare function provide<T>(key: InjectionKey<T> | string | number, value: T): void;
|
|
584
|
+
export declare function inject<T>(key: InjectionKey<T> | string): T | undefined;
|
|
585
|
+
export declare function inject<T>(key: InjectionKey<T> | string, defaultValue: T, treatDefaultAsFactory?: false): T;
|
|
586
|
+
export declare function inject<T>(key: InjectionKey<T> | string, defaultValue: T | (() => T), treatDefaultAsFactory: true): T;
|
|
587
|
+
export declare interface InjectionKey<T> extends Symbol {}
|
|
588
|
+
|
|
573
589
|
// nextTick
|
|
574
590
|
export function nextTick (fn: () => any): void
|
|
575
591
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/core",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.69",
|
|
4
4
|
"description": "mpx runtime core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"miniprogram",
|
|
@@ -19,21 +19,23 @@
|
|
|
19
19
|
],
|
|
20
20
|
"main": "src/index.js",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@mpxjs/utils": "^2.9.
|
|
22
|
+
"@mpxjs/utils": "^2.9.69",
|
|
23
23
|
"lodash": "^4.1.1",
|
|
24
24
|
"miniprogram-api-typings": "^3.10.0"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"@ant-design/react-native": "^5.1.3",
|
|
28
|
+
"@d11/react-native-fast-image": "^8.6.12",
|
|
28
29
|
"@mpxjs/api-proxy": "^2.9.0",
|
|
29
30
|
"@mpxjs/store": "^2.9.0",
|
|
30
|
-
"@react-navigation/native": "^
|
|
31
|
-
"@react-navigation/
|
|
31
|
+
"@react-navigation/native": "^7.0.3",
|
|
32
|
+
"@react-navigation/stack": "^7.0.4",
|
|
32
33
|
"react": "*",
|
|
33
34
|
"react-native": "*",
|
|
34
35
|
"react-native-gesture-handler": "^2.19.0",
|
|
35
36
|
"react-native-linear-gradient": "^2.8.3",
|
|
36
|
-
"react-native-safe-area-context": "^4.
|
|
37
|
+
"react-native-safe-area-context": "^4.14.0",
|
|
38
|
+
"react-native-screens": "^4.1.0",
|
|
37
39
|
"react-native-webview": "^13.10.5",
|
|
38
40
|
"vue": "^2.7.10",
|
|
39
41
|
"vue-demi": "^0.14.6",
|
|
@@ -62,7 +64,7 @@
|
|
|
62
64
|
"@react-navigation/native": {
|
|
63
65
|
"optional": true
|
|
64
66
|
},
|
|
65
|
-
"@react-navigation/
|
|
67
|
+
"@react-navigation/stack": {
|
|
66
68
|
"optional": true
|
|
67
69
|
},
|
|
68
70
|
"@ant-design/react-native": {
|
|
@@ -71,6 +73,9 @@
|
|
|
71
73
|
"react-native-safe-area-context": {
|
|
72
74
|
"optional": true
|
|
73
75
|
},
|
|
76
|
+
"react-native-screens": {
|
|
77
|
+
"optional": true
|
|
78
|
+
},
|
|
74
79
|
"react-native-webview": {
|
|
75
80
|
"optional": true
|
|
76
81
|
},
|
|
@@ -79,6 +84,9 @@
|
|
|
79
84
|
},
|
|
80
85
|
"react-native-linear-gradient": {
|
|
81
86
|
"optional": true
|
|
87
|
+
},
|
|
88
|
+
"@d11/react-native-fast-image": {
|
|
89
|
+
"optional": true
|
|
82
90
|
}
|
|
83
91
|
},
|
|
84
92
|
"publishConfig": {
|
|
@@ -97,5 +105,5 @@
|
|
|
97
105
|
"url": "https://github.com/didi/mpx/issues"
|
|
98
106
|
},
|
|
99
107
|
"sideEffects": false,
|
|
100
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "e23c51acc4c2ffdd31fcc6c27aae1aed42d1ade2"
|
|
101
109
|
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import { implemented } from '../core/implement'
|
|
6
6
|
|
|
7
7
|
// 暂不支持的wx选项,后期需要各种花式支持
|
|
8
|
-
const unsupported = ['relations', 'moved', 'definitionFilter'
|
|
8
|
+
const unsupported = ['relations', 'moved', 'definitionFilter']
|
|
9
9
|
|
|
10
10
|
function convertErrorDesc (key) {
|
|
11
11
|
error(`Options.${key} is not supported in runtime conversion from wx to react native.`, global.currentResource)
|
package/src/core/mergeOptions.js
CHANGED
|
@@ -354,7 +354,7 @@ function transformHOOKS (options) {
|
|
|
354
354
|
const componentHooksMap = makeMap(convertRule.lifecycle.component)
|
|
355
355
|
for (const key in options) {
|
|
356
356
|
// 使用Component创建page实例,页面专属生命周期&自定义方法需写在methods内部
|
|
357
|
-
if (typeof options[key] === 'function' && key !== 'dataFn' && key !== 'setup' && !componentHooksMap[key]) {
|
|
357
|
+
if (typeof options[key] === 'function' && key !== 'dataFn' && key !== 'setup' && key !== 'provide' && !componentHooksMap[key]) {
|
|
358
358
|
if (!options.methods) options.methods = {}
|
|
359
359
|
options.methods[key] = options[key]
|
|
360
360
|
delete options[key]
|
package/src/core/proxy.js
CHANGED
|
@@ -8,10 +8,12 @@ import Mpx from '../index'
|
|
|
8
8
|
import {
|
|
9
9
|
noop,
|
|
10
10
|
type,
|
|
11
|
+
isArray,
|
|
11
12
|
isFunction,
|
|
12
13
|
isObject,
|
|
13
14
|
isEmptyObject,
|
|
14
15
|
isPlainObject,
|
|
16
|
+
isWeb,
|
|
15
17
|
doGetByPath,
|
|
16
18
|
getByPath,
|
|
17
19
|
setByPath,
|
|
@@ -25,6 +27,7 @@ import {
|
|
|
25
27
|
processUndefined,
|
|
26
28
|
getFirstKey,
|
|
27
29
|
callWithErrorHandling,
|
|
30
|
+
wrapMethodsWithErrorHandling,
|
|
28
31
|
warn,
|
|
29
32
|
error,
|
|
30
33
|
getEnvObj
|
|
@@ -47,6 +50,7 @@ import {
|
|
|
47
50
|
} from './innerLifecycle'
|
|
48
51
|
import contextMap from '../dynamic/vnode/context'
|
|
49
52
|
import { getAst } from '../dynamic/astCache'
|
|
53
|
+
import { inject, provide } from '../platform/export/apiInject'
|
|
50
54
|
|
|
51
55
|
let uid = 0
|
|
52
56
|
|
|
@@ -160,11 +164,15 @@ export default class MpxProxy {
|
|
|
160
164
|
// web中BEFORECREATE钩子通过vue的beforeCreate钩子单独驱动
|
|
161
165
|
this.callHook(BEFORECREATE)
|
|
162
166
|
setCurrentInstance(this)
|
|
167
|
+
// 在 props/data 初始化之前初始化 inject
|
|
168
|
+
this.initInject()
|
|
163
169
|
this.initProps()
|
|
164
170
|
this.initSetup()
|
|
165
171
|
this.initData()
|
|
166
172
|
this.initComputed()
|
|
167
173
|
this.initWatch()
|
|
174
|
+
// 在 props/data 初始化之后初始化 provide
|
|
175
|
+
this.initProvide()
|
|
168
176
|
unsetCurrentInstance()
|
|
169
177
|
}
|
|
170
178
|
|
|
@@ -219,6 +227,16 @@ export default class MpxProxy {
|
|
|
219
227
|
// 页面/组件销毁清除上下文的缓存
|
|
220
228
|
contextMap.remove(this.uid)
|
|
221
229
|
}
|
|
230
|
+
if (!isWeb && this.options.__type__ === 'page') {
|
|
231
|
+
// 小程序页面销毁时移除对应的 provide
|
|
232
|
+
if (isFunction(this.target.getPageId)) {
|
|
233
|
+
const pageId = this.target.getPageId()
|
|
234
|
+
const providesMap = global.__mpxProvidesMap
|
|
235
|
+
if (providesMap.__pages[pageId]) {
|
|
236
|
+
delete providesMap.__pages[pageId]
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
222
240
|
this.callHook(BEFOREUNMOUNT)
|
|
223
241
|
this.scope?.stop()
|
|
224
242
|
if (this.update) this.update.active = false
|
|
@@ -277,7 +295,7 @@ export default class MpxProxy {
|
|
|
277
295
|
initSetup () {
|
|
278
296
|
const setup = this.options.setup
|
|
279
297
|
if (setup) {
|
|
280
|
-
|
|
298
|
+
let setupResult = callWithErrorHandling(setup, this, 'setup function', [
|
|
281
299
|
this.props,
|
|
282
300
|
{
|
|
283
301
|
triggerEvent: this.target.triggerEvent ? this.target.triggerEvent.bind(this.target) : noop,
|
|
@@ -294,6 +312,7 @@ export default class MpxProxy {
|
|
|
294
312
|
error(`Setup() should return a object, received: ${type(setupResult)}.`, this.options.mpxFileResource)
|
|
295
313
|
return
|
|
296
314
|
}
|
|
315
|
+
setupResult = wrapMethodsWithErrorHandling(setupResult, this)
|
|
297
316
|
proxy(this.target, setupResult, undefined, false, this.createProxyConflictHandler('setup result'))
|
|
298
317
|
this.collectLocalKeys(setupResult, (key, val) => !isFunction(val))
|
|
299
318
|
}
|
|
@@ -350,6 +369,55 @@ export default class MpxProxy {
|
|
|
350
369
|
}
|
|
351
370
|
}
|
|
352
371
|
|
|
372
|
+
initProvide () {
|
|
373
|
+
const provideOpt = this.options.provide
|
|
374
|
+
if (provideOpt) {
|
|
375
|
+
const provided = isFunction(provideOpt)
|
|
376
|
+
? callWithErrorHandling(provideOpt.bind(this.target), this, 'provide function')
|
|
377
|
+
: provideOpt
|
|
378
|
+
if (!isObject(provided)) {
|
|
379
|
+
return
|
|
380
|
+
}
|
|
381
|
+
Object.keys(provided).forEach(key => {
|
|
382
|
+
provide(key, provided[key])
|
|
383
|
+
})
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
initInject () {
|
|
388
|
+
const injectOpt = this.options.inject
|
|
389
|
+
if (injectOpt) {
|
|
390
|
+
this.resolveInject(injectOpt)
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
resolveInject (injectOpt) {
|
|
395
|
+
if (isArray(injectOpt)) {
|
|
396
|
+
const normalized = {}
|
|
397
|
+
for (let i = 0; i < injectOpt.length; i++) {
|
|
398
|
+
normalized[injectOpt[i]] = injectOpt[i]
|
|
399
|
+
}
|
|
400
|
+
injectOpt = normalized
|
|
401
|
+
}
|
|
402
|
+
const injectObj = {}
|
|
403
|
+
for (const key in injectOpt) {
|
|
404
|
+
const opt = injectOpt[key]
|
|
405
|
+
let injected
|
|
406
|
+
if (isObject(opt)) {
|
|
407
|
+
if ('default' in opt) {
|
|
408
|
+
injected = inject(opt.from || key, opt.default, true)
|
|
409
|
+
} else {
|
|
410
|
+
injected = inject(opt.from || key)
|
|
411
|
+
}
|
|
412
|
+
} else {
|
|
413
|
+
injected = inject(opt)
|
|
414
|
+
}
|
|
415
|
+
injectObj[key] = injected
|
|
416
|
+
}
|
|
417
|
+
proxy(this.target, injectObj, undefined, false, this.createProxyConflictHandler('inject'))
|
|
418
|
+
this.collectLocalKeys(injectObj)
|
|
419
|
+
}
|
|
420
|
+
|
|
353
421
|
watch (source, cb, options) {
|
|
354
422
|
const target = this.target
|
|
355
423
|
const getter = isString(source)
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { isObject, isArray, dash2hump,
|
|
1
|
+
import { isObject, isArray, dash2hump, cached } from '@mpxjs/utils'
|
|
2
2
|
import { Dimensions, StyleSheet } from 'react-native'
|
|
3
3
|
|
|
4
|
+
let { width, height } = Dimensions.get('screen')
|
|
5
|
+
|
|
6
|
+
Dimensions.addEventListener('change', ({ screen }) => {
|
|
7
|
+
width = screen.width
|
|
8
|
+
height = screen.height
|
|
9
|
+
})
|
|
10
|
+
|
|
4
11
|
function rpx (value) {
|
|
5
|
-
const { width } = Dimensions.get('screen')
|
|
6
12
|
// rn 单位 dp = 1(css)px = 1 物理像素 * pixelRatio(像素比)
|
|
7
13
|
// px = rpx * (750 / 屏幕宽度)
|
|
8
14
|
return value * width / 750
|
|
9
15
|
}
|
|
10
16
|
function vw (value) {
|
|
11
|
-
const { width } = Dimensions.get('screen')
|
|
12
17
|
return value * width / 100
|
|
13
18
|
}
|
|
14
19
|
function vh (value) {
|
|
15
|
-
const navigation = getFocusedNavigation()
|
|
16
|
-
const height = navigation?.layout?.height || Dimensions.get('screen').height
|
|
17
20
|
return value * height / 100
|
|
18
21
|
}
|
|
19
22
|
|
|
@@ -24,14 +27,15 @@ const unit = {
|
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
function formatValue (value) {
|
|
27
|
-
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const matched = unitRegExp.exec(value)
|
|
31
|
+
if (matched) {
|
|
32
|
+
if (!matched[2] || matched[2] === 'px') {
|
|
33
|
+
return +matched[1]
|
|
34
|
+
} else {
|
|
35
|
+
return unit[matched[2]](+matched[1])
|
|
36
|
+
}
|
|
34
37
|
}
|
|
38
|
+
if (hairlineRegExp.test(value)) return StyleSheet.hairlineWidth
|
|
35
39
|
return value
|
|
36
40
|
}
|
|
37
41
|
|
|
@@ -106,8 +110,7 @@ function stringifyDynamicClass (value) {
|
|
|
106
110
|
|
|
107
111
|
const listDelimiter = /;(?![^(]*[)])/g
|
|
108
112
|
const propertyDelimiter = /:(.+)/
|
|
109
|
-
const unitRegExp = /^\s*(-?\d+(?:\.\d+)?)(rpx|vw|vh)
|
|
110
|
-
const numberRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/
|
|
113
|
+
const unitRegExp = /^\s*(-?\d+(?:\.\d+)?)(rpx|vw|vh|px)?\s*$/
|
|
111
114
|
const hairlineRegExp = /^\s*hairlineWidth\s*$/
|
|
112
115
|
const varRegExp = /^--/
|
|
113
116
|
|
|
@@ -164,14 +167,8 @@ export default function styleHelperMixin () {
|
|
|
164
167
|
},
|
|
165
168
|
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, hide) {
|
|
166
169
|
const result = {}
|
|
167
|
-
const classMap = {}
|
|
168
|
-
|
|
169
|
-
if (isFunction(global.__getAppClassMap)) {
|
|
170
|
-
Object.assign(classMap, global.__getAppClassMap())
|
|
171
|
-
}
|
|
172
|
-
if (isFunction(this.__getClassMap)) {
|
|
173
|
-
Object.assign(classMap, this.__getClassMap())
|
|
174
|
-
}
|
|
170
|
+
const classMap = this.__getClassMap?.() || {}
|
|
171
|
+
const appClassMap = global.__getAppClassMap?.() || {}
|
|
175
172
|
|
|
176
173
|
if (staticClass || dynamicClass) {
|
|
177
174
|
// todo 当前为了复用小程序unocss产物,暂时进行mpEscape,等后续正式支持unocss后可不进行mpEscape
|
|
@@ -179,6 +176,9 @@ export default function styleHelperMixin () {
|
|
|
179
176
|
classString.split(/\s+/).forEach((className) => {
|
|
180
177
|
if (classMap[className]) {
|
|
181
178
|
Object.assign(result, classMap[className])
|
|
179
|
+
} else if (appClassMap[className]) {
|
|
180
|
+
// todo 全局样式在每个页面和组件中生效,以支持全局原子类,后续支持样式模块复用后可考虑移除
|
|
181
|
+
Object.assign(result, appClassMap[className])
|
|
182
182
|
} else if (this.props[className] && isObject(this.props[className])) {
|
|
183
183
|
// externalClasses必定以对象形式传递下来
|
|
184
184
|
Object.assign(result, this.props[className])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import transferOptions from '../core/transferOptions'
|
|
2
2
|
import builtInKeysMap from './patch/builtInKeysMap'
|
|
3
|
-
import { makeMap, spreadProp } from '@mpxjs/utils'
|
|
3
|
+
import { makeMap, spreadProp, parseUrlQuery, getFocusedNavigation } from '@mpxjs/utils'
|
|
4
4
|
import { mergeLifecycle } from '../convertor/mergeLifecycle'
|
|
5
5
|
import * as wxLifecycle from '../platform/patch/wx/lifecycle'
|
|
6
6
|
import Mpx from '../index'
|
|
@@ -40,7 +40,7 @@ function createAppInstance (appData) {
|
|
|
40
40
|
export default function createApp (option, config = {}) {
|
|
41
41
|
const appData = {}
|
|
42
42
|
|
|
43
|
-
const { NavigationContainer,
|
|
43
|
+
const { NavigationContainer, createStackNavigator, SafeAreaProvider } = global.__navigationHelper
|
|
44
44
|
// app选项目前不需要进行转换
|
|
45
45
|
const { rawOptions, currentInject } = transferOptions(option, 'app', false)
|
|
46
46
|
const defaultOptions = filterOptions(spreadProp(rawOptions, 'methods'), appData)
|
|
@@ -51,16 +51,25 @@ export default function createApp (option, config = {}) {
|
|
|
51
51
|
}
|
|
52
52
|
const pages = currentInject.getPages() || {}
|
|
53
53
|
const firstPage = currentInject.firstPage
|
|
54
|
-
const Stack =
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
const Stack = createStackNavigator()
|
|
55
|
+
const getPageScreens = (initialRouteName, initialParams) => {
|
|
56
|
+
return Object.entries(pages).map(([key, item]) => {
|
|
57
|
+
if (key === initialRouteName) {
|
|
58
|
+
return createElement(Stack.Screen, {
|
|
59
|
+
name: key,
|
|
60
|
+
component: item,
|
|
61
|
+
initialParams
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
return createElement(Stack.Screen, {
|
|
65
|
+
name: key,
|
|
66
|
+
component: item
|
|
67
|
+
})
|
|
60
68
|
})
|
|
61
|
-
}
|
|
69
|
+
}
|
|
62
70
|
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
|
|
63
|
-
const onStateChange = () => {
|
|
71
|
+
const onStateChange = (state) => {
|
|
72
|
+
Mpx.config.rnConfig.onStateChange?.(state)
|
|
64
73
|
if (global.__navigationHelper.lastSuccessCallback) {
|
|
65
74
|
global.__navigationHelper.lastSuccessCallback()
|
|
66
75
|
global.__navigationHelper.lastSuccessCallback = null
|
|
@@ -81,26 +90,48 @@ export default function createApp (option, config = {}) {
|
|
|
81
90
|
error: []
|
|
82
91
|
}
|
|
83
92
|
|
|
93
|
+
global.__mpxAppLaunched = false
|
|
94
|
+
|
|
84
95
|
global.__mpxAppFocusedState = ref('show')
|
|
85
|
-
global.__mpxOptionsMap[currentInject.moduleId] = memo(() => {
|
|
96
|
+
global.__mpxOptionsMap[currentInject.moduleId] = memo((props) => {
|
|
86
97
|
const instanceRef = useRef(null)
|
|
87
98
|
if (!instanceRef.current) {
|
|
88
99
|
instanceRef.current = createAppInstance(appData)
|
|
89
100
|
}
|
|
90
101
|
const instance = instanceRef.current
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
const initialRouteRef = useRef({
|
|
103
|
+
initialRouteName: firstPage,
|
|
104
|
+
initialParams: {}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
if (!global.__mpxAppLaunched) {
|
|
108
|
+
const parsed = Mpx.config.rnConfig.parseAppProps?.(props) || {}
|
|
109
|
+
if (parsed.url) {
|
|
110
|
+
const { path, queryObj } = parseUrlQuery(parsed.url)
|
|
111
|
+
Object.assign(initialRouteRef.current, {
|
|
112
|
+
initialRouteName: path.startsWith('/') ? path.slice(1) : path,
|
|
113
|
+
initialParams: queryObj
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
global.__mpxAppOnLaunch = (navigation) => {
|
|
117
|
+
global.__mpxAppLaunched = true
|
|
118
|
+
const state = navigation.getState()
|
|
119
|
+
Mpx.config.rnConfig.onStateChange?.(state)
|
|
120
|
+
const current = state.routes[state.index]
|
|
121
|
+
global.__mpxEnterOptions = {
|
|
122
|
+
path: current.name,
|
|
123
|
+
query: current.params,
|
|
124
|
+
scene: 0,
|
|
125
|
+
shareTicket: '',
|
|
126
|
+
referrerInfo: {}
|
|
127
|
+
}
|
|
128
|
+
defaultOptions.onLaunch && defaultOptions.onLaunch.call(instance, global.__mpxEnterOptions)
|
|
129
|
+
defaultOptions.onShow && defaultOptions.onShow.call(instance, global.__mpxEnterOptions)
|
|
99
130
|
}
|
|
100
|
-
|
|
101
|
-
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
useEffect(() => {
|
|
102
134
|
if (defaultOptions.onShow) {
|
|
103
|
-
defaultOptions.onShow.call(instance, options)
|
|
104
135
|
global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(instance))
|
|
105
136
|
}
|
|
106
137
|
if (defaultOptions.onHide) {
|
|
@@ -112,6 +143,19 @@ export default function createApp (option, config = {}) {
|
|
|
112
143
|
|
|
113
144
|
const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => {
|
|
114
145
|
if (currentState === 'active') {
|
|
146
|
+
let options = global.__mpxEnterOptions
|
|
147
|
+
const navigation = getFocusedNavigation()
|
|
148
|
+
if (navigation) {
|
|
149
|
+
const state = navigation.getState()
|
|
150
|
+
const current = state.routes[state.index]
|
|
151
|
+
options = {
|
|
152
|
+
path: current.name,
|
|
153
|
+
query: current.params,
|
|
154
|
+
scene: 0,
|
|
155
|
+
shareTicket: '',
|
|
156
|
+
referrerInfo: {}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
115
159
|
global.__mpxAppCbs.show.forEach((cb) => {
|
|
116
160
|
cb(options)
|
|
117
161
|
})
|
|
@@ -138,26 +182,33 @@ export default function createApp (option, config = {}) {
|
|
|
138
182
|
}
|
|
139
183
|
}, [])
|
|
140
184
|
|
|
185
|
+
const { initialRouteName, initialParams } = initialRouteRef.current
|
|
141
186
|
return createElement(SafeAreaProvider,
|
|
142
187
|
null,
|
|
143
188
|
createElement(NavigationContainer,
|
|
144
189
|
{
|
|
145
|
-
ref: navigationRef,
|
|
146
190
|
onStateChange,
|
|
147
191
|
onUnhandledAction
|
|
148
192
|
},
|
|
149
193
|
createElement(Stack.Navigator,
|
|
150
194
|
{
|
|
151
|
-
initialRouteName
|
|
195
|
+
initialRouteName,
|
|
196
|
+
screenOptions: {
|
|
197
|
+
gestureEnabled: true,
|
|
198
|
+
// 7.x替换headerBackTitleVisible
|
|
199
|
+
// headerBackButtonDisplayMode: 'minimal',
|
|
200
|
+
headerBackTitleVisible: false,
|
|
201
|
+
headerMode: 'float'
|
|
202
|
+
}
|
|
152
203
|
},
|
|
153
|
-
...
|
|
204
|
+
...getPageScreens(initialRouteName, initialParams)
|
|
154
205
|
)
|
|
155
206
|
)
|
|
156
207
|
)
|
|
157
208
|
})
|
|
158
209
|
|
|
159
210
|
global.getCurrentPages = function () {
|
|
160
|
-
const navigation =
|
|
211
|
+
const navigation = getFocusedNavigation()
|
|
161
212
|
if (navigation) {
|
|
162
213
|
return navigation.getState().routes.map((route) => {
|
|
163
214
|
return global.__mpxPagesMap[route.key] && global.__mpxPagesMap[route.key][0]
|
|
@@ -5,6 +5,7 @@ import { makeMap, spreadProp, isBrowser } from '@mpxjs/utils'
|
|
|
5
5
|
import { mergeLifecycle } from '../convertor/mergeLifecycle'
|
|
6
6
|
import * as webLifecycle from '../platform/patch/web/lifecycle'
|
|
7
7
|
import Mpx from '../index'
|
|
8
|
+
import { initAppProvides } from './export/apiInject'
|
|
8
9
|
|
|
9
10
|
const webAppHooksMap = makeMap(mergeLifecycle(webLifecycle.LIFECYCLE).app)
|
|
10
11
|
|
|
@@ -14,7 +15,7 @@ function filterOptions (options, appData) {
|
|
|
14
15
|
if (builtInKeysMap[key]) {
|
|
15
16
|
return
|
|
16
17
|
}
|
|
17
|
-
if (__mpx_mode__ === 'web' && !webAppHooksMap[key]) {
|
|
18
|
+
if (__mpx_mode__ === 'web' && !webAppHooksMap[key] && key !== 'provide') {
|
|
18
19
|
appData[key] = options[key]
|
|
19
20
|
} else {
|
|
20
21
|
newOptions[key] = options[key]
|
|
@@ -87,6 +88,7 @@ export default function createApp (option, config = {}) {
|
|
|
87
88
|
return appData
|
|
88
89
|
}
|
|
89
90
|
} else {
|
|
91
|
+
initAppProvides(rawOptions)
|
|
90
92
|
defaultOptions.onAppInit && defaultOptions.onAppInit()
|
|
91
93
|
const ctor = config.customCtor || global.currentCtor || App
|
|
92
94
|
ctor(defaultOptions)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { callWithErrorHandling, isFunction, isObject, warn } from '@mpxjs/utils'
|
|
2
|
+
import { currentInstance } from '../../core/proxy'
|
|
3
|
+
|
|
4
|
+
const providesMap = {
|
|
5
|
+
/** 全局 scope */
|
|
6
|
+
__app: Object.create(null),
|
|
7
|
+
/** 页面 scope */
|
|
8
|
+
__pages: Object.create(null)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
global.__mpxProvidesMap = providesMap
|
|
12
|
+
|
|
13
|
+
/** @internal createApp() 初始化应用层 scope provide */
|
|
14
|
+
export function initAppProvides (appOptions) {
|
|
15
|
+
const provideOpt = appOptions.provide
|
|
16
|
+
if (provideOpt) {
|
|
17
|
+
const provided = isFunction(provideOpt)
|
|
18
|
+
? callWithErrorHandling(provideOpt.bind(appOptions), appOptions, 'createApp provide function')
|
|
19
|
+
: provideOpt
|
|
20
|
+
if (isObject(provided)) {
|
|
21
|
+
providesMap.__app = provided
|
|
22
|
+
} else {
|
|
23
|
+
warn('App provides must be an object or a function that returns an object.')
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function resolvePageId (context) {
|
|
29
|
+
if (context && isFunction(context.getPageId)) {
|
|
30
|
+
return context.getPageId()
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function resolvePageProvides (context) {
|
|
35
|
+
const pageId = resolvePageId(context)
|
|
36
|
+
return providesMap.__pages[pageId] || (providesMap.__pages[pageId] = Object.create(null))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function provide (key, value) {
|
|
40
|
+
const instance = currentInstance
|
|
41
|
+
if (!instance) {
|
|
42
|
+
warn('provide() can only be used inside setup().')
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
// 小程序无法实现组件父级引用,所以 provide scope 设置为组件所在页面
|
|
46
|
+
const provides = resolvePageProvides(instance.target)
|
|
47
|
+
provides[key] = value
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function inject (key, defaultValue, treatDefaultAsFactory = false) {
|
|
51
|
+
const instance = currentInstance
|
|
52
|
+
if (!instance) {
|
|
53
|
+
warn('inject() can only be used inside setup()')
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
const provides = resolvePageProvides(instance.target)
|
|
57
|
+
if (key in provides) {
|
|
58
|
+
return provides[key]
|
|
59
|
+
} else if (key in providesMap.__app) {
|
|
60
|
+
return providesMap.__app[key]
|
|
61
|
+
} else if (arguments.length > 1) {
|
|
62
|
+
return treatDefaultAsFactory && isFunction(defaultValue)
|
|
63
|
+
? defaultValue.call(instance && instance.target)
|
|
64
|
+
: defaultValue
|
|
65
|
+
} else {
|
|
66
|
+
warn(`injection "${String(key)}" not found.`)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { provide, inject } from 'vue'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import MpxProxy from '../../../core/proxy'
|
|
2
2
|
import builtInKeysMap from '../builtInKeysMap'
|
|
3
3
|
import mergeOptions from '../../../core/mergeOptions'
|
|
4
|
-
import { error, diffAndCloneA, hasOwn, noop } from '@mpxjs/utils'
|
|
4
|
+
import { error, diffAndCloneA, hasOwn, noop, wrapMethodsWithErrorHandling } from '@mpxjs/utils'
|
|
5
5
|
|
|
6
6
|
function transformApiForProxy (context, currentInject) {
|
|
7
7
|
const rawSetData = context.setData.bind(context)
|
|
@@ -100,12 +100,25 @@ function filterOptions (options, type) {
|
|
|
100
100
|
if (!hasOwn(newOptions, 'props')) {
|
|
101
101
|
newOptions.props = Object.assign({}, options.props, options.properties)
|
|
102
102
|
}
|
|
103
|
-
} else if (key === 'methods'
|
|
104
|
-
|
|
103
|
+
} else if (key === 'methods') {
|
|
104
|
+
const newMethods = wrapMethodsWithErrorHandling(options[key])
|
|
105
|
+
if (type === 'page') {
|
|
106
|
+
// 构造器为Page时抽取所有methods方法到顶层
|
|
107
|
+
Object.assign(newOptions, newMethods)
|
|
108
|
+
} else {
|
|
109
|
+
newOptions[key] = newMethods
|
|
110
|
+
}
|
|
111
|
+
} else if (key === 'behaviors') {
|
|
112
|
+
newOptions.mixins = options[key]
|
|
105
113
|
} else {
|
|
106
114
|
newOptions[key] = options[key]
|
|
107
115
|
}
|
|
108
116
|
})
|
|
117
|
+
if (newOptions.relations) {
|
|
118
|
+
// ali relations 需要设置 options.relations = true
|
|
119
|
+
newOptions.options = newOptions.options || {}
|
|
120
|
+
newOptions.options.relations = true
|
|
121
|
+
}
|
|
109
122
|
return newOptions
|
|
110
123
|
}
|
|
111
124
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, useMemo, useCallback, createElement, memo, forwardRef, useImperativeHandle, useContext,
|
|
1
|
+
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, useMemo, useCallback, createElement, memo, forwardRef, useImperativeHandle, useContext, Fragment, cloneElement } from 'react'
|
|
2
2
|
import * as ReactNative from 'react-native'
|
|
3
3
|
import { ReactiveEffect } from '../../../observer/effect'
|
|
4
4
|
import { watch } from '../../../observer/watch'
|
|
5
5
|
import { reactive, set, del } from '../../../observer/reactive'
|
|
6
|
-
import { hasOwn, isFunction, noop, isObject, getByPath, collectDataset, hump2dash } from '@mpxjs/utils'
|
|
6
|
+
import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, wrapMethodsWithErrorHandling } from '@mpxjs/utils'
|
|
7
7
|
import MpxProxy from '../../../core/proxy'
|
|
8
8
|
import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE, REACTHOOKSEXEC } from '../../../core/innerLifecycle'
|
|
9
9
|
import mergeOptions from '../../../core/mergeOptions'
|
|
10
10
|
import { queueJob } from '../../../observer/scheduler'
|
|
11
11
|
import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy'
|
|
12
|
-
import { IntersectionObserverContext } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context'
|
|
12
|
+
import { IntersectionObserverContext, RouteContext } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context'
|
|
13
13
|
|
|
14
14
|
function getSystemInfo () {
|
|
15
15
|
const window = ReactNative.Dimensions.get('window')
|
|
@@ -105,26 +105,33 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
105
105
|
this.__refs = {}
|
|
106
106
|
this.__dispatchedSlotSet = new WeakSet()
|
|
107
107
|
},
|
|
108
|
-
__getSlot (name) {
|
|
108
|
+
__getSlot (name, slot) {
|
|
109
109
|
const { children } = propsRef.current
|
|
110
110
|
if (children) {
|
|
111
|
-
|
|
112
|
-
if (
|
|
111
|
+
let result = []
|
|
112
|
+
if (isArray(children) && !hasOwn(children, '__slot')) {
|
|
113
113
|
children.forEach(child => {
|
|
114
|
-
if (child
|
|
114
|
+
if (isObject(child) && hasOwn(child, '__slot')) {
|
|
115
|
+
if (child.__slot === name) result.push(...child)
|
|
116
|
+
} else if (child?.props?.slot === name) {
|
|
115
117
|
result.push(child)
|
|
116
118
|
}
|
|
117
119
|
})
|
|
118
120
|
} else {
|
|
119
|
-
if (children
|
|
121
|
+
if (isObject(children) && hasOwn(children, '__slot')) {
|
|
122
|
+
if (children.__slot === name) result.push(...children)
|
|
123
|
+
} else if (children?.props?.slot === name) {
|
|
120
124
|
result.push(children)
|
|
121
125
|
}
|
|
122
126
|
}
|
|
123
|
-
|
|
127
|
+
result = result.filter(item => {
|
|
124
128
|
if (!isObject(item) || this.__dispatchedSlotSet.has(item)) return false
|
|
125
129
|
this.__dispatchedSlotSet.add(item)
|
|
126
130
|
return true
|
|
127
131
|
})
|
|
132
|
+
if (!result.length) return null
|
|
133
|
+
result.__slot = slot
|
|
134
|
+
return result
|
|
128
135
|
}
|
|
129
136
|
return null
|
|
130
137
|
},
|
|
@@ -134,7 +141,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
134
141
|
_i (val, fn) {
|
|
135
142
|
let i, l, keys, key
|
|
136
143
|
const result = []
|
|
137
|
-
if (
|
|
144
|
+
if (isArray(val) || typeof val === 'string') {
|
|
138
145
|
for (i = 0, l = val.length; i < l; i++) {
|
|
139
146
|
result.push(fn.call(this, val[i], i))
|
|
140
147
|
}
|
|
@@ -266,8 +273,6 @@ function hasPageHook (mpxProxy, hookNames) {
|
|
|
266
273
|
})
|
|
267
274
|
}
|
|
268
275
|
|
|
269
|
-
const RouteContext = createContext(null)
|
|
270
|
-
|
|
271
276
|
const triggerPageStatusHook = (mpxProxy, event) => {
|
|
272
277
|
mpxProxy.callHook(event === 'show' ? ONSHOW : ONHIDE)
|
|
273
278
|
const pageLifetimes = mpxProxy.options.pageLifetimes
|
|
@@ -347,6 +352,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
347
352
|
rawOptions = mergeOptions(rawOptions, type, false)
|
|
348
353
|
const components = Object.assign({}, rawOptions.components, currentInject.getComponents())
|
|
349
354
|
const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
|
|
355
|
+
if (rawOptions.methods) rawOptions.methods = wrapMethodsWithErrorHandling(rawOptions.methods)
|
|
350
356
|
const defaultOptions = memo(forwardRef((props, ref) => {
|
|
351
357
|
const instanceRef = useRef(null)
|
|
352
358
|
const propsRef = useRef(null)
|
|
@@ -365,7 +371,21 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
365
371
|
|
|
366
372
|
const proxy = instance.__mpxProxy
|
|
367
373
|
|
|
368
|
-
proxy.callHook(REACTHOOKSEXEC)
|
|
374
|
+
let hooksResult = proxy.callHook(REACTHOOKSEXEC, [props])
|
|
375
|
+
if (isObject(hooksResult)) {
|
|
376
|
+
hooksResult = wrapMethodsWithErrorHandling(hooksResult, proxy)
|
|
377
|
+
if (isFirst) {
|
|
378
|
+
const onConflict = proxy.createProxyConflictHandler('react hooks result')
|
|
379
|
+
Object.keys(hooksResult).forEach((key) => {
|
|
380
|
+
if (key in proxy.target) {
|
|
381
|
+
onConflict(key)
|
|
382
|
+
}
|
|
383
|
+
proxy.target[key] = hooksResult[key]
|
|
384
|
+
})
|
|
385
|
+
} else {
|
|
386
|
+
Object.assign(proxy.target, hooksResult)
|
|
387
|
+
}
|
|
388
|
+
}
|
|
369
389
|
|
|
370
390
|
useEffect(() => {
|
|
371
391
|
if (!isFirst) {
|
|
@@ -391,6 +411,9 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
391
411
|
|
|
392
412
|
useEffect(() => {
|
|
393
413
|
if (type === 'page') {
|
|
414
|
+
if (!global.__mpxAppLaunched && global.__mpxAppOnLaunch) {
|
|
415
|
+
global.__mpxAppOnLaunch(props.navigation)
|
|
416
|
+
}
|
|
394
417
|
proxy.callHook(ONLOAD, [props.route.params || {}])
|
|
395
418
|
}
|
|
396
419
|
proxy.mounted()
|
|
@@ -429,29 +452,20 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
429
452
|
|
|
430
453
|
useLayoutEffect(() => {
|
|
431
454
|
const isCustom = pageConfig.navigationStyle === 'custom'
|
|
432
|
-
let opt = {}
|
|
433
|
-
if (__mpx_mode__ === 'android') {
|
|
434
|
-
opt = {
|
|
435
|
-
statusBarTranslucent: isCustom,
|
|
436
|
-
statusBarStyle: pageConfig.statusBarStyle, // 枚举值 'auto' | 'dark' | 'light' 控制statusbar字体颜色
|
|
437
|
-
statusBarColor: isCustom ? 'transparent' : pageConfig.statusBarColor // 控制statusbar背景颜色
|
|
438
|
-
}
|
|
439
|
-
} else if (__mpx_mode__ === 'ios') {
|
|
440
|
-
opt = {
|
|
441
|
-
headerBackTitleVisible: false
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
455
|
navigation.setOptions({
|
|
445
456
|
headerShown: !isCustom,
|
|
446
|
-
|
|
447
|
-
headerTitle: pageConfig.navigationBarTitleText || '',
|
|
457
|
+
title: pageConfig.navigationBarTitleText || '',
|
|
448
458
|
headerStyle: {
|
|
449
459
|
backgroundColor: pageConfig.navigationBarBackgroundColor || '#000000'
|
|
450
460
|
},
|
|
451
|
-
|
|
452
|
-
headerTintColor: pageConfig.navigationBarTextStyle || 'white',
|
|
453
|
-
...opt
|
|
461
|
+
headerTintColor: pageConfig.navigationBarTextStyle || 'white'
|
|
454
462
|
})
|
|
463
|
+
if (__mpx_mode__ === 'android') {
|
|
464
|
+
ReactNative.StatusBar.setBarStyle(pageConfig.barStyle || 'dark-content')
|
|
465
|
+
ReactNative.StatusBar.setTranslucent(isCustom) // 控制statusbar是否占位
|
|
466
|
+
const color = isCustom ? 'transparent' : pageConfig.statusBarColor
|
|
467
|
+
color && ReactNative.StatusBar.setBackgroundColor(color)
|
|
468
|
+
}
|
|
455
469
|
}, [])
|
|
456
470
|
|
|
457
471
|
const rootRef = useRef(null)
|
|
@@ -484,9 +498,9 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
484
498
|
value: currentPageId
|
|
485
499
|
},
|
|
486
500
|
createElement(IntersectionObserverContext.Provider,
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
501
|
+
{
|
|
502
|
+
value: intersectionObservers.current
|
|
503
|
+
},
|
|
490
504
|
createElement(defaultOptions,
|
|
491
505
|
{
|
|
492
506
|
navigation,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import builtInKeysMap from '../builtInKeysMap'
|
|
2
2
|
import mergeOptions from '../../../core/mergeOptions'
|
|
3
|
-
import { diffAndCloneA, hasOwn } from '@mpxjs/utils'
|
|
3
|
+
import { diffAndCloneA, hasOwn, wrapMethodsWithErrorHandling } from '@mpxjs/utils'
|
|
4
4
|
import { getCurrentInstance as getCurrentVueInstance } from '../../export/index'
|
|
5
5
|
import MpxProxy, { setCurrentInstance, unsetCurrentInstance } from '../../../core/proxy'
|
|
6
6
|
import {
|
|
@@ -27,6 +27,8 @@ function filterOptions (options) {
|
|
|
27
27
|
)
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
} else if (key === 'methods') {
|
|
31
|
+
newOptions[key] = wrapMethodsWithErrorHandling(options[key])
|
|
30
32
|
} else {
|
|
31
33
|
newOptions[key] = options[key]
|
|
32
34
|
}
|
|
@@ -62,7 +64,7 @@ export function getDefaultOptions ({ type, rawOptions = {} }) {
|
|
|
62
64
|
}
|
|
63
65
|
const setupRes = rawSetup(props, newContext)
|
|
64
66
|
unsetCurrentInstance(instance.__mpxProxy)
|
|
65
|
-
return setupRes
|
|
67
|
+
return wrapMethodsWithErrorHandling(setupRes, instance.__mpxProxy)
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
const rootMixins = [{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasOwn, noop, isFunction } from '@mpxjs/utils'
|
|
1
|
+
import { hasOwn, noop, isFunction, wrapMethodsWithErrorHandling } from '@mpxjs/utils'
|
|
2
2
|
import MpxProxy from '../../../core/proxy'
|
|
3
3
|
import builtInKeysMap from '../builtInKeysMap'
|
|
4
4
|
import mergeOptions from '../../../core/mergeOptions'
|
|
@@ -140,9 +140,14 @@ export function filterOptions (options) {
|
|
|
140
140
|
if (!hasOwn(newOptions, 'properties')) {
|
|
141
141
|
newOptions.properties = transformProperties(Object.assign({}, options.props, options.properties))
|
|
142
142
|
}
|
|
143
|
-
} else if (key === 'methods'
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
} else if (key === 'methods') {
|
|
144
|
+
const newMethods = wrapMethodsWithErrorHandling(options[key])
|
|
145
|
+
if (options.__pageCtor__) {
|
|
146
|
+
// 构造器为Page时抽取所有methods方法到顶层
|
|
147
|
+
Object.assign(newOptions, newMethods)
|
|
148
|
+
} else {
|
|
149
|
+
newOptions[key] = newMethods
|
|
150
|
+
}
|
|
146
151
|
} else {
|
|
147
152
|
newOptions[key] = options[key]
|
|
148
153
|
}
|
|
@@ -6,6 +6,9 @@ const factoryMap = {
|
|
|
6
6
|
|
|
7
7
|
module.exports = (type) => (...args) => {
|
|
8
8
|
if (type === 'Behavior') {
|
|
9
|
+
if (__mpx_mode__ === 'ali') {
|
|
10
|
+
return Mixin.apply(null, args)
|
|
11
|
+
}
|
|
9
12
|
if (args[0]) {
|
|
10
13
|
Object.defineProperty(args[0], '__mpx_behaviors_to_mixins__', {
|
|
11
14
|
configurable: true,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { getDefaultOptions } from './getDefaultOptions.ios'
|