@mpxjs/core 2.9.59 → 2.9.64
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 +1 -1
- package/@types/index.d.ts +29 -56
- package/@types/node.d.ts +0 -2
- package/package.json +11 -3
- package/src/convertor/wxToReact.js +1 -1
- package/src/core/innerLifecycle.js +2 -0
- package/src/core/mergeOptions.js +1 -1
- package/src/core/proxy.js +26 -7
- package/src/index.js +11 -7
- package/src/platform/builtInMixins/directiveHelperMixin.ios.js +1 -7
- package/src/platform/builtInMixins/index.js +3 -3
- package/src/platform/builtInMixins/refsMixin.ios.js +27 -48
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +86 -36
- package/src/platform/createApp.ios.js +1 -1
- package/src/platform/patch/index.js +1 -1
- package/src/platform/patch/react/getDefaultOptions.ios.js +99 -85
- package/src/platform/patch/wx/lifecycle.js +10 -3
package/@types/global.d.ts
CHANGED
package/@types/index.d.ts
CHANGED
|
@@ -7,10 +7,8 @@
|
|
|
7
7
|
/// <reference path="./global.d.ts" />
|
|
8
8
|
/// <reference path="./node.d.ts" />
|
|
9
9
|
|
|
10
|
-
// @ts-ignore
|
|
11
10
|
import { GetComputedType } from '@mpxjs/store'
|
|
12
11
|
|
|
13
|
-
// @ts-ignore
|
|
14
12
|
export * from '@mpxjs/store'
|
|
15
13
|
|
|
16
14
|
// utils
|
|
@@ -34,17 +32,17 @@ type Data = object | (() => object)
|
|
|
34
32
|
export type PropType<T> = {
|
|
35
33
|
__type: T
|
|
36
34
|
} & (
|
|
37
|
-
|
|
35
|
+
T extends string
|
|
38
36
|
? StringConstructor
|
|
39
37
|
: T extends number
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
? NumberConstructor
|
|
39
|
+
: T extends boolean
|
|
40
|
+
? BooleanConstructor
|
|
41
|
+
: T extends any[]
|
|
42
|
+
? ArrayConstructor
|
|
43
|
+
: T extends object
|
|
44
|
+
? ObjectConstructor
|
|
45
|
+
: never
|
|
48
46
|
)
|
|
49
47
|
|
|
50
48
|
type FullPropType<T> = {
|
|
@@ -85,10 +83,10 @@ type GetDataType<T> = T extends () => any ? ReturnType<T> : T
|
|
|
85
83
|
|
|
86
84
|
type GetPropsType<T extends Properties> = {
|
|
87
85
|
readonly [K in keyof T]: T[K] extends FullPropType<infer V>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
? V
|
|
87
|
+
: T[K] extends PropType<infer V>
|
|
88
|
+
? V
|
|
89
|
+
: WechatMiniprogram.Component.PropertyToData<T[K]>
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
type RequiredPropertyNames<T> = {
|
|
@@ -246,7 +244,7 @@ export function injectMixins (mixins: object | Array<object>, options?: MixinTyp
|
|
|
246
244
|
// export function watch (expr: string | (() => any), handler: WatchHandler | WatchOptWithHandler, options?: WatchOpt): () => void
|
|
247
245
|
|
|
248
246
|
interface AnyConstructor {
|
|
249
|
-
new
|
|
247
|
+
new(...args: any[]): any
|
|
250
248
|
|
|
251
249
|
prototype: any
|
|
252
250
|
}
|
|
@@ -266,6 +264,7 @@ interface MpxConfig {
|
|
|
266
264
|
setDataHandler: (data: object, target: ComponentIns<{}, {}, {}, {}, []>) => any | null
|
|
267
265
|
forceFlushSync: boolean,
|
|
268
266
|
webRouteConfig: object,
|
|
267
|
+
webConfig: object,
|
|
269
268
|
webviewConfig?: WebviewConfig
|
|
270
269
|
}
|
|
271
270
|
|
|
@@ -285,9 +284,9 @@ export type Plugin = PluginInstallFunction | {
|
|
|
285
284
|
install: PluginInstallFunction
|
|
286
285
|
}
|
|
287
286
|
|
|
288
|
-
export type PluginFunction<T extends Plugin> = T extends PluginInstallFunction ? T : T extends { install: infer U } ? U : never
|
|
287
|
+
export type PluginFunction<T extends Plugin> = T extends PluginInstallFunction ? T : T extends { install: infer U } ? U : never
|
|
289
288
|
|
|
290
|
-
export type PluginFunctionParams<T extends PluginInstallFunction> = T extends (app: any, ...args: infer P) => any ? P : []
|
|
289
|
+
export type PluginFunctionParams<T extends PluginInstallFunction> = T extends (app: any, ...args: infer P) => any ? P : []
|
|
291
290
|
|
|
292
291
|
export interface Mpx {
|
|
293
292
|
getMixin: typeof getMixin
|
|
@@ -297,7 +296,7 @@ export interface Mpx {
|
|
|
297
296
|
observable: typeof observable
|
|
298
297
|
watch: typeof watch
|
|
299
298
|
|
|
300
|
-
use
|
|
299
|
+
use<T extends Plugin = Plugin> (plugin: T, ...rest: PluginFunctionParams<PluginFunction<T>>): Mpx
|
|
301
300
|
|
|
302
301
|
implement (name: string, options?: ImplementOptions): void
|
|
303
302
|
|
|
@@ -376,8 +375,8 @@ export interface RefUnwrapBailTypes {
|
|
|
376
375
|
export type UnwrapRef<T> = T extends ShallowRef<infer V>
|
|
377
376
|
? V
|
|
378
377
|
: T extends Ref<infer V>
|
|
379
|
-
|
|
380
|
-
|
|
378
|
+
? UnwrapRefSimple<V>
|
|
379
|
+
: UnwrapRefSimple<T>
|
|
381
380
|
|
|
382
381
|
export type UnwrapRefSimple<T> = T extends | Function
|
|
383
382
|
| CollectionTypes
|
|
@@ -386,10 +385,10 @@ export type UnwrapRefSimple<T> = T extends | Function
|
|
|
386
385
|
| RefUnwrapBailTypes[keyof RefUnwrapBailTypes]
|
|
387
386
|
? T
|
|
388
387
|
: T extends Array<any>
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
388
|
+
? { [K in keyof T]: UnwrapRefSimple<T[K]> }
|
|
389
|
+
: T extends object & { [ShallowReactiveMarker]?: never } // not a shallowReactive
|
|
390
|
+
? { [P in keyof T]: P extends symbol ? T[P] : UnwrapRef<T[P]> }
|
|
391
|
+
: T
|
|
393
392
|
|
|
394
393
|
// If the the type T accepts type "any", output type Y, otherwise output type N.
|
|
395
394
|
// https://stackoverflow.com/questions/49927523/disallow-call-with-any/49928360#49928360
|
|
@@ -426,9 +425,7 @@ export interface ComputedRef<T = any> extends WritableComputedRef<T> {
|
|
|
426
425
|
[ComputedRefSymbol]: true
|
|
427
426
|
}
|
|
428
427
|
|
|
429
|
-
export
|
|
430
|
-
// readonly effect: ReactiveEffect<T>
|
|
431
|
-
}
|
|
428
|
+
export type WritableComputedRef<T> = Ref<T>
|
|
432
429
|
|
|
433
430
|
type WatchCallback<T> = (
|
|
434
431
|
value: T,
|
|
@@ -462,7 +459,6 @@ interface EffectScope {
|
|
|
462
459
|
resume (ignoreDirty?: boolean): void
|
|
463
460
|
}
|
|
464
461
|
|
|
465
|
-
|
|
466
462
|
type StringObj = {
|
|
467
463
|
[k: string]: string | StringObj
|
|
468
464
|
}
|
|
@@ -489,7 +485,6 @@ interface UseI18n {
|
|
|
489
485
|
mergeLocaleMessage (locale: string, messages: StringObj): void
|
|
490
486
|
}
|
|
491
487
|
|
|
492
|
-
|
|
493
488
|
export function ref<T extends object> (
|
|
494
489
|
value: T
|
|
495
490
|
): [T] extends [Ref] ? T : Ref<UnwrapRef<T>>
|
|
@@ -529,7 +524,6 @@ export function computed<T> (
|
|
|
529
524
|
options: WritableComputedOptions<T>
|
|
530
525
|
): WritableComputedRef<T>
|
|
531
526
|
|
|
532
|
-
|
|
533
527
|
export function watchEffect (
|
|
534
528
|
effect: (onCleanup: (cleanupFn: () => void) => void) => void,
|
|
535
529
|
options?: WatchEffectOptions
|
|
@@ -545,7 +539,6 @@ export function watchPostEffect (
|
|
|
545
539
|
options?: WatchEffectOptions
|
|
546
540
|
): void
|
|
547
541
|
|
|
548
|
-
|
|
549
542
|
export function watch<T extends MultiWatchSources> (
|
|
550
543
|
sources: [...T],
|
|
551
544
|
callback: WatchCallback<{
|
|
@@ -572,13 +565,9 @@ export function watch<T extends Reactive<object>> ( // for reactive value
|
|
|
572
565
|
): () => void
|
|
573
566
|
|
|
574
567
|
export function effectScope (detached?: boolean): EffectScope
|
|
575
|
-
|
|
576
568
|
export function getCurrentScope (): EffectScope | undefined
|
|
577
|
-
|
|
578
569
|
export function onScopeDispose (fn: () => void): void
|
|
579
|
-
|
|
580
570
|
export function set<T extends object> (target: T, key: string | number, value: any): void
|
|
581
|
-
|
|
582
571
|
export function del<T extends object> (target: T, key: keyof T): void
|
|
583
572
|
|
|
584
573
|
// nextTick
|
|
@@ -586,43 +575,25 @@ export function nextTick (fn: () => any): void
|
|
|
586
575
|
|
|
587
576
|
// lifecycle
|
|
588
577
|
export function onBeforeMount (callback: () => void): void
|
|
589
|
-
|
|
590
578
|
export function onMounted (callback: () => void): void
|
|
591
|
-
|
|
592
579
|
export function onBeforeUpdate (callback: () => void): void
|
|
593
|
-
|
|
594
580
|
export function onUpdated (callback: () => void): void
|
|
595
|
-
|
|
596
581
|
export function onBeforeUnmount (callback: () => void): void
|
|
597
|
-
|
|
598
582
|
export function onUnmounted (callback: () => void): void
|
|
599
|
-
|
|
600
583
|
export function onLoad<T extends Record<string, string | undefined>> (callback: (query: T) => void): void
|
|
601
|
-
|
|
602
|
-
// wechat dose not have generics
|
|
603
|
-
// export function onLoad (callback: WechatMiniprogram.Page.ILifetime['onLoad']): void
|
|
604
|
-
|
|
605
584
|
export function onShow (callback: WechatMiniprogram.Page.ILifetime['onShow']): void
|
|
606
|
-
|
|
607
585
|
export function onHide (callback: WechatMiniprogram.Page.ILifetime['onHide']): void
|
|
608
|
-
|
|
609
586
|
export function onResize (callback: WechatMiniprogram.Page.ILifetime['onResize']): void
|
|
610
|
-
|
|
611
587
|
export function onPullDownRefresh (callback: WechatMiniprogram.Page.ILifetime['onPullDownRefresh']): void
|
|
612
|
-
|
|
613
588
|
export function onReachBottom (callback: WechatMiniprogram.Page.ILifetime['onReachBottom']): void
|
|
614
|
-
|
|
615
589
|
export function onShareAppMessage (callback: WechatMiniprogram.Page.ILifetime['onShareAppMessage']): void
|
|
616
|
-
|
|
617
590
|
export function onShareTimeline (callback: WechatMiniprogram.Page.ILifetime['onShareTimeline']): void
|
|
618
|
-
|
|
619
591
|
export function onAddToFavorites (callback: WechatMiniprogram.Page.ILifetime['onAddToFavorites']): void
|
|
620
|
-
|
|
621
592
|
export function onPageScroll (callback: WechatMiniprogram.Page.ILifetime['onPageScroll']): void
|
|
622
|
-
|
|
623
593
|
export function onTabItemTap (callback: WechatMiniprogram.Page.ILifetime['onTabItemTap']): void
|
|
624
|
-
|
|
625
594
|
export function onSaveExitState (callback: () => void): void
|
|
595
|
+
export function onServerPrefetch (callback: () => any): void
|
|
596
|
+
export function onReactHooksExec (callback: () => void): void
|
|
626
597
|
|
|
627
598
|
// get instance
|
|
628
599
|
export function getCurrentInstance<T extends ComponentIns<{}, {}, {}>> (): { proxy: T, [x: string]: any }
|
|
@@ -672,6 +643,8 @@ export const ONLOAD: string
|
|
|
672
643
|
export const ONSHOW: string
|
|
673
644
|
export const ONHIDE: string
|
|
674
645
|
export const ONRESIZE: string
|
|
646
|
+
export const SERVERPREFETCH: string
|
|
647
|
+
export const REACTHOOKSEXEC: string
|
|
675
648
|
|
|
676
649
|
declare global {
|
|
677
650
|
const defineProps: (<T extends Properties = {}>(props: T) => Readonly<GetPropsType<T>>) & (<T>() => Readonly<T>)
|
package/@types/node.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
1
|
declare let global: Record<string, any> // in web, we use global varible to do some things, here to declare
|
|
3
2
|
|
|
4
3
|
type Dict<T> = {
|
|
@@ -7,7 +6,6 @@ type Dict<T> = {
|
|
|
7
6
|
|
|
8
7
|
type EnvType = Dict<string>
|
|
9
8
|
|
|
10
|
-
// @ts-ignore
|
|
11
9
|
declare let process: {
|
|
12
10
|
env: EnvType
|
|
13
11
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/core",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.64",
|
|
4
4
|
"description": "mpx runtime core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"miniprogram",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"main": "src/index.js",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@mpxjs/utils": "^2.9.
|
|
22
|
+
"@mpxjs/utils": "^2.9.64",
|
|
23
23
|
"lodash": "^4.1.1",
|
|
24
24
|
"miniprogram-api-typings": "^3.10.0"
|
|
25
25
|
},
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
"@react-navigation/native-stack": "^6.9.26",
|
|
32
32
|
"react": "*",
|
|
33
33
|
"react-native": "*",
|
|
34
|
+
"react-native-gesture-handler": "^2.19.0",
|
|
34
35
|
"react-native-safe-area-context": "^4.10.1",
|
|
36
|
+
"react-native-webview": "^13.10.5",
|
|
35
37
|
"vue": "^2.7.10",
|
|
36
38
|
"vue-demi": "^0.14.6",
|
|
37
39
|
"vue-i18n": "^8.27.2",
|
|
@@ -67,6 +69,12 @@
|
|
|
67
69
|
},
|
|
68
70
|
"react-native-safe-area-context": {
|
|
69
71
|
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"react-native-webview": {
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"react-native-gesture-handler": {
|
|
77
|
+
"optional": true
|
|
70
78
|
}
|
|
71
79
|
},
|
|
72
80
|
"publishConfig": {
|
|
@@ -85,5 +93,5 @@
|
|
|
85
93
|
"url": "https://github.com/didi/mpx/issues"
|
|
86
94
|
},
|
|
87
95
|
"sideEffects": false,
|
|
88
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "803334dc0e600f219d514c27461aa7663b7a6653"
|
|
89
97
|
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import { implemented } from '../core/implement'
|
|
6
6
|
|
|
7
7
|
// 暂不支持的wx选项,后期需要各种花式支持
|
|
8
|
-
const unsupported = ['relations', 'moved', 'definitionFilter', 'onShareAppMessage'
|
|
8
|
+
const unsupported = ['relations', 'moved', 'definitionFilter', 'onShareAppMessage']
|
|
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)
|
|
@@ -11,6 +11,7 @@ export const ONSHOW = '__onShow__'
|
|
|
11
11
|
export const ONHIDE = '__onHide__'
|
|
12
12
|
export const ONRESIZE = '__onResize__'
|
|
13
13
|
export const SERVERPREFETCH = '__serverPrefetch__'
|
|
14
|
+
export const REACTHOOKSEXEC = '__reactHooksExec__'
|
|
14
15
|
|
|
15
16
|
export const INNER_LIFECYCLES = [
|
|
16
17
|
BEFORECREATE,
|
|
@@ -21,6 +22,7 @@ export const INNER_LIFECYCLES = [
|
|
|
21
22
|
UPDATED,
|
|
22
23
|
BEFOREUNMOUNT,
|
|
23
24
|
SERVERPREFETCH,
|
|
25
|
+
REACTHOOKSEXEC,
|
|
24
26
|
UNMOUNTED,
|
|
25
27
|
ONLOAD,
|
|
26
28
|
ONSHOW,
|
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' &&
|
|
357
|
+
if (typeof options[key] === 'function' && key !== 'dataFn' && key !== 'setup' && !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
|
@@ -42,7 +42,8 @@ import {
|
|
|
42
42
|
ONLOAD,
|
|
43
43
|
ONSHOW,
|
|
44
44
|
ONHIDE,
|
|
45
|
-
ONRESIZE
|
|
45
|
+
ONRESIZE,
|
|
46
|
+
REACTHOOKSEXEC
|
|
46
47
|
} from './innerLifecycle'
|
|
47
48
|
import contextMap from '../dynamic/vnode/context'
|
|
48
49
|
import { getAst } from '../dynamic/astCache'
|
|
@@ -498,11 +499,28 @@ export default class MpxProxy {
|
|
|
498
499
|
return result
|
|
499
500
|
}
|
|
500
501
|
|
|
501
|
-
doRenderWithVNode (vnode) {
|
|
502
|
+
doRenderWithVNode (vnode, cb) {
|
|
503
|
+
const renderTask = this.createRenderTask()
|
|
504
|
+
let callback = cb
|
|
505
|
+
// mounted之后才会触发BEFOREUPDATE/UPDATED
|
|
506
|
+
if (this.isMounted()) {
|
|
507
|
+
this.callHook(BEFOREUPDATE)
|
|
508
|
+
callback = () => {
|
|
509
|
+
cb && cb()
|
|
510
|
+
this.callHook(UPDATED)
|
|
511
|
+
renderTask && renderTask.resolve()
|
|
512
|
+
}
|
|
513
|
+
}
|
|
502
514
|
if (!this._vnode) {
|
|
503
|
-
this.
|
|
515
|
+
this._vnode = diffAndCloneA(vnode).clone
|
|
516
|
+
pauseTracking()
|
|
517
|
+
// 触发渲染时暂停数据响应追踪,避免误收集到子组件的数据依赖
|
|
518
|
+
this.target.__render({ r: vnode }, callback)
|
|
519
|
+
resetTracking()
|
|
504
520
|
} else {
|
|
505
|
-
|
|
521
|
+
const result = diffAndCloneA(vnode, this._vnode)
|
|
522
|
+
this._vnode = result.clone
|
|
523
|
+
let diffPath = result.diffData
|
|
506
524
|
if (!isEmptyObject(diffPath)) {
|
|
507
525
|
// 构造 diffPath 数据
|
|
508
526
|
diffPath = Object.keys(diffPath).reduce((preVal, curVal) => {
|
|
@@ -510,11 +528,11 @@ export default class MpxProxy {
|
|
|
510
528
|
preVal[key] = diffPath[curVal]
|
|
511
529
|
return preVal
|
|
512
530
|
}, {})
|
|
513
|
-
|
|
531
|
+
pauseTracking()
|
|
532
|
+
this.target.__render(diffPath, callback)
|
|
533
|
+
resetTracking()
|
|
514
534
|
}
|
|
515
535
|
}
|
|
516
|
-
// 缓存本地的 vnode 用以下一次 diff
|
|
517
|
-
this._vnode = diffAndCloneA(vnode).clone
|
|
518
536
|
}
|
|
519
537
|
|
|
520
538
|
doRender (data, cb) {
|
|
@@ -734,6 +752,7 @@ export const onShow = createHook(ONSHOW)
|
|
|
734
752
|
export const onHide = createHook(ONHIDE)
|
|
735
753
|
export const onResize = createHook(ONRESIZE)
|
|
736
754
|
export const onServerPrefetch = createHook(SERVERPREFETCH)
|
|
755
|
+
export const onReactHooksExec = createHook(REACTHOOKSEXEC)
|
|
737
756
|
export const onPullDownRefresh = createHook('__onPullDownRefresh__')
|
|
738
757
|
export const onReachBottom = createHook('__onReachBottom__')
|
|
739
758
|
export const onShareAppMessage = createHook('__onShareAppMessage__')
|
package/src/index.js
CHANGED
|
@@ -29,11 +29,12 @@ export {
|
|
|
29
29
|
UPDATED,
|
|
30
30
|
BEFOREUNMOUNT,
|
|
31
31
|
UNMOUNTED,
|
|
32
|
-
SERVERPREFETCH,
|
|
33
32
|
ONLOAD,
|
|
34
33
|
ONSHOW,
|
|
35
34
|
ONHIDE,
|
|
36
|
-
ONRESIZE
|
|
35
|
+
ONRESIZE,
|
|
36
|
+
SERVERPREFETCH,
|
|
37
|
+
REACTHOOKSEXEC
|
|
37
38
|
} from './core/innerLifecycle'
|
|
38
39
|
|
|
39
40
|
export {
|
|
@@ -43,7 +44,6 @@ export {
|
|
|
43
44
|
onUpdated,
|
|
44
45
|
onBeforeUnmount,
|
|
45
46
|
onUnmounted,
|
|
46
|
-
onServerPrefetch,
|
|
47
47
|
onLoad,
|
|
48
48
|
onShow,
|
|
49
49
|
onHide,
|
|
@@ -55,7 +55,9 @@ export {
|
|
|
55
55
|
onAddToFavorites,
|
|
56
56
|
onPageScroll,
|
|
57
57
|
onTabItemTap,
|
|
58
|
-
onSaveExitState
|
|
58
|
+
onSaveExitState,
|
|
59
|
+
onServerPrefetch,
|
|
60
|
+
onReactHooksExec
|
|
59
61
|
} from './core/proxy'
|
|
60
62
|
|
|
61
63
|
export { getMixin } from './core/mergeOptions'
|
|
@@ -136,19 +138,21 @@ Mpx.config = {
|
|
|
136
138
|
ignoreProxyWhiteList: ['id', 'dataset', 'data'],
|
|
137
139
|
observeClassInstance: false,
|
|
138
140
|
errorHandler: null,
|
|
141
|
+
warnHandler: null,
|
|
139
142
|
proxyEventHandler: null,
|
|
140
143
|
setDataHandler: null,
|
|
141
144
|
forceFlushSync: false,
|
|
142
145
|
webRouteConfig: {},
|
|
146
|
+
webConfig: {},
|
|
143
147
|
/*
|
|
144
148
|
支持两个属性
|
|
145
149
|
hostWhitelists Array 类型 支持h5域名白名单安全校验
|
|
146
150
|
apiImplementations webview JSSDK接口 例如getlocation
|
|
147
151
|
*/
|
|
148
152
|
webviewConfig: {},
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
/**
|
|
154
|
+
* react-native 相关配置,用于挂载事件等,如 onShareAppMessage
|
|
155
|
+
*/
|
|
152
156
|
rnConfig: {}
|
|
153
157
|
}
|
|
154
158
|
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { warn, type } from '@mpxjs/utils'
|
|
2
1
|
export default function directiveHelperMixin () {
|
|
3
2
|
return {
|
|
4
3
|
methods: {
|
|
5
4
|
__getWxKey (item, key) {
|
|
6
|
-
|
|
7
|
-
if (typeof value === 'string' || typeof value === 'number') {
|
|
8
|
-
return value
|
|
9
|
-
} else {
|
|
10
|
-
warn(`wx:key's value should return a string or a number, received: ${type(value)}`, this.__mpxProxy.options.mpxFileResource)
|
|
11
|
-
}
|
|
5
|
+
return key === '*this' ? item : item[key]
|
|
12
6
|
}
|
|
13
7
|
}
|
|
14
8
|
}
|
|
@@ -14,13 +14,13 @@ import { dynamicRefsMixin, dynamicRenderHelperMixin, dynamicSlotMixin } from '..
|
|
|
14
14
|
import styleHelperMixin from './styleHelperMixin'
|
|
15
15
|
import directiveHelperMixin from './directiveHelperMixin'
|
|
16
16
|
|
|
17
|
-
export default function getBuiltInMixins (
|
|
17
|
+
export default function getBuiltInMixins ({ type, rawOptions = {} }) {
|
|
18
18
|
let bulitInMixins
|
|
19
19
|
if (__mpx_mode__ === 'ios' || __mpx_mode__ === 'android') {
|
|
20
20
|
bulitInMixins = [
|
|
21
21
|
proxyEventMixin(),
|
|
22
22
|
directiveHelperMixin(),
|
|
23
|
-
styleHelperMixin(
|
|
23
|
+
styleHelperMixin(),
|
|
24
24
|
refsMixin(),
|
|
25
25
|
i18nMixin()
|
|
26
26
|
]
|
|
@@ -46,7 +46,7 @@ export default function getBuiltInMixins (options, type) {
|
|
|
46
46
|
relationsMixin(type)
|
|
47
47
|
]
|
|
48
48
|
// 此为纯增强类mixins,原生模式下不需要注入
|
|
49
|
-
if (!
|
|
49
|
+
if (!rawOptions.__nativeRender__) {
|
|
50
50
|
bulitInMixins = bulitInMixins.concat([
|
|
51
51
|
renderHelperMixin(),
|
|
52
52
|
showMixin(type),
|
|
@@ -1,76 +1,55 @@
|
|
|
1
|
-
import { BEFORECREATE
|
|
1
|
+
import { BEFORECREATE } from '../../core/innerLifecycle'
|
|
2
2
|
import { createSelectorQuery } from '@mpxjs/api-proxy'
|
|
3
|
-
import { computed } from '../../observer/computed'
|
|
4
3
|
|
|
5
4
|
export default function getRefsMixin () {
|
|
6
5
|
return {
|
|
7
6
|
[BEFORECREATE] () {
|
|
8
7
|
this.__refs = {}
|
|
9
8
|
this.$refs = {}
|
|
10
|
-
},
|
|
11
|
-
// __getRefs强依赖数据响应,需要在CREATED中执行
|
|
12
|
-
[CREATED] () {
|
|
13
9
|
this.__getRefs()
|
|
14
10
|
},
|
|
15
11
|
methods: {
|
|
16
12
|
__getRefs () {
|
|
17
13
|
const refs = this.__getRefsData() || []
|
|
18
14
|
const target = this
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const selector = prefix + item
|
|
30
|
-
selectorMap[selector] = selectorMap[selector] || []
|
|
31
|
-
selectorMap[selector].push({ type, key })
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
} else {
|
|
35
|
-
selectorMap[key] = selectorMap[key] || []
|
|
36
|
-
selectorMap[key].push({ type, key })
|
|
15
|
+
refs.forEach(({ key, type, all }) => {
|
|
16
|
+
Object.defineProperty(this.$refs, key, {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
get () {
|
|
20
|
+
if (type === 'component') {
|
|
21
|
+
return all ? target.selectAllComponents(key) : target.selectComponent(key)
|
|
22
|
+
} else {
|
|
23
|
+
return createSelectorQuery().in(target).select(key, all)
|
|
24
|
+
}
|
|
37
25
|
}
|
|
38
26
|
})
|
|
39
|
-
return selectorMap
|
|
40
27
|
})
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
28
|
+
},
|
|
29
|
+
__getRefVal (type, selectorsConf) {
|
|
30
|
+
return (instance) => {
|
|
31
|
+
if (instance) {
|
|
32
|
+
selectorsConf.forEach((item = []) => {
|
|
33
|
+
const [prefix, selectors = ''] = item
|
|
34
|
+
if (selectors) {
|
|
35
|
+
selectors.trim().split(/\s+/).forEach(selector => {
|
|
36
|
+
const refKey = prefix + selector
|
|
37
|
+
this.__refs[refKey] = this.__refs[refKey] || []
|
|
38
|
+
this.__refs[refKey].push({ type, instance })
|
|
39
|
+
})
|
|
54
40
|
}
|
|
55
41
|
})
|
|
56
42
|
}
|
|
57
|
-
})
|
|
58
|
-
},
|
|
59
|
-
__getRefVal (key) {
|
|
60
|
-
if (!this.__refs[key]) {
|
|
61
|
-
this.__refs[key] = []
|
|
62
43
|
}
|
|
63
|
-
return (instance) => instance && this.__refs[key].push(instance)
|
|
64
44
|
},
|
|
65
45
|
__selectRef (selector, refType, all = false) {
|
|
66
|
-
const splitedSelector = selector.match(/(#|\.)
|
|
46
|
+
const splitedSelector = selector.match(/(#|\.)?[^.#]+/g) || []
|
|
67
47
|
const refsArr = splitedSelector.map(selector => {
|
|
68
|
-
const
|
|
48
|
+
const refs = this.__refs[selector] || []
|
|
69
49
|
const res = []
|
|
70
|
-
|
|
50
|
+
refs.forEach(({ type, instance }) => {
|
|
71
51
|
if (type === refType) {
|
|
72
|
-
|
|
73
|
-
res.push(..._refs)
|
|
52
|
+
res.push(instance)
|
|
74
53
|
}
|
|
75
54
|
})
|
|
76
55
|
return res
|
|
@@ -1,8 +1,59 @@
|
|
|
1
|
-
import { isObject, isArray, dash2hump, isFunction } from '@mpxjs/utils'
|
|
2
|
-
import { Dimensions } from 'react-native'
|
|
1
|
+
import { isObject, isArray, dash2hump, isFunction, cached } from '@mpxjs/utils'
|
|
2
|
+
import { Dimensions, StyleSheet } from 'react-native'
|
|
3
3
|
|
|
4
|
-
function
|
|
5
|
-
|
|
4
|
+
function rpx (value) {
|
|
5
|
+
const { width } = Dimensions.get('screen')
|
|
6
|
+
// rn 单位 dp = 1(css)px = 1 物理像素 * pixelRatio(像素比)
|
|
7
|
+
// px = rpx * (750 / 屏幕宽度)
|
|
8
|
+
return value * width / 750
|
|
9
|
+
}
|
|
10
|
+
function vw (value) {
|
|
11
|
+
const { width } = Dimensions.get('screen')
|
|
12
|
+
return value * width / 100
|
|
13
|
+
}
|
|
14
|
+
function vh (value) {
|
|
15
|
+
const { height } = Dimensions.get('screen')
|
|
16
|
+
return value * height / 100
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
global.__unit = {
|
|
20
|
+
rpx,
|
|
21
|
+
vw,
|
|
22
|
+
vh
|
|
23
|
+
}
|
|
24
|
+
global.__hairlineWidth = StyleSheet.hairlineWidth
|
|
25
|
+
|
|
26
|
+
const escapeReg = /[()[\]{}#!.:,%'"+$]/g
|
|
27
|
+
const escapeMap = {
|
|
28
|
+
'(': '_pl_',
|
|
29
|
+
')': '_pr_',
|
|
30
|
+
'[': '_bl_',
|
|
31
|
+
']': '_br_',
|
|
32
|
+
'{': '_cl_',
|
|
33
|
+
'}': '_cr_',
|
|
34
|
+
'#': '_h_',
|
|
35
|
+
'!': '_i_',
|
|
36
|
+
'/': '_s_',
|
|
37
|
+
'.': '_d_',
|
|
38
|
+
':': '_c_',
|
|
39
|
+
',': '_2c_',
|
|
40
|
+
'%': '_p_',
|
|
41
|
+
'\'': '_q_',
|
|
42
|
+
'"': '_dq_',
|
|
43
|
+
'+': '_a_',
|
|
44
|
+
$: '_si_'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const mpEscape = cached((str) => {
|
|
48
|
+
return str.replace(escapeReg, function (match) {
|
|
49
|
+
if (escapeMap[match]) return escapeMap[match]
|
|
50
|
+
// unknown escaped
|
|
51
|
+
return '_u_'
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
function concat (a = '', b = '') {
|
|
56
|
+
return a ? b ? (a + ' ' + b) : a : b
|
|
6
57
|
}
|
|
7
58
|
|
|
8
59
|
function stringifyArray (value) {
|
|
@@ -41,10 +92,12 @@ function stringifyDynamicClass (value) {
|
|
|
41
92
|
|
|
42
93
|
const listDelimiter = /;(?![^(]*[)])/g
|
|
43
94
|
const propertyDelimiter = /:(.+)/
|
|
44
|
-
const
|
|
45
|
-
const
|
|
95
|
+
const unitRegExp = /^\s*(-?\d+(?:\.\d+)?)(rpx|vw|vh)\s*$/
|
|
96
|
+
const numberRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/
|
|
97
|
+
const hairlineRegExp = /^\s*hairlineWidth\s*$/
|
|
98
|
+
const varRegExp = /^--/
|
|
46
99
|
|
|
47
|
-
|
|
100
|
+
const parseStyleText = cached((cssText = '') => {
|
|
48
101
|
const res = {}
|
|
49
102
|
const arr = cssText.split(listDelimiter)
|
|
50
103
|
for (let i = 0; i < arr.length; i++) {
|
|
@@ -52,13 +105,14 @@ function parseStyleText (cssText) {
|
|
|
52
105
|
if (item) {
|
|
53
106
|
const tmp = item.split(propertyDelimiter)
|
|
54
107
|
if (tmp.length > 1) {
|
|
55
|
-
|
|
108
|
+
let k = tmp[0].trim()
|
|
109
|
+
k = varRegExp.test(k) ? k : dash2hump(k)
|
|
56
110
|
res[k] = tmp[1].trim()
|
|
57
111
|
}
|
|
58
112
|
}
|
|
59
113
|
}
|
|
60
114
|
return res
|
|
61
|
-
}
|
|
115
|
+
})
|
|
62
116
|
|
|
63
117
|
function normalizeDynamicStyle (value) {
|
|
64
118
|
if (!value) return {}
|
|
@@ -79,65 +133,61 @@ function mergeObjectArray (arr) {
|
|
|
79
133
|
return res
|
|
80
134
|
}
|
|
81
135
|
|
|
82
|
-
function transformStyleObj (
|
|
136
|
+
function transformStyleObj (styleObj) {
|
|
83
137
|
const keys = Object.keys(styleObj)
|
|
84
138
|
const transformed = {}
|
|
85
139
|
keys.forEach((prop) => {
|
|
86
|
-
// todo 检测不支持的prop
|
|
87
140
|
let value = styleObj[prop]
|
|
88
141
|
let matched
|
|
89
|
-
if ((matched =
|
|
142
|
+
if ((matched = numberRegExp.exec(value))) {
|
|
90
143
|
value = +matched[1]
|
|
91
|
-
} else if ((matched =
|
|
92
|
-
value =
|
|
144
|
+
} else if ((matched = unitRegExp.exec(value))) {
|
|
145
|
+
value = global.__unit[matched[2]](+matched[1])
|
|
146
|
+
} else if (hairlineRegExp.test(value)) {
|
|
147
|
+
value = StyleSheet.hairlineWidth
|
|
93
148
|
}
|
|
94
|
-
// todo 检测不支持的value
|
|
95
149
|
transformed[prop] = value
|
|
96
150
|
})
|
|
97
151
|
return transformed
|
|
98
152
|
}
|
|
99
153
|
|
|
100
|
-
export default function styleHelperMixin (
|
|
154
|
+
export default function styleHelperMixin () {
|
|
101
155
|
return {
|
|
102
156
|
methods: {
|
|
103
|
-
__rpx (value) {
|
|
104
|
-
const { width } = Dimensions.get('screen')
|
|
105
|
-
// rn 单位 dp = 1(css)px = 1 物理像素 * pixelRatio(像素比)
|
|
106
|
-
// px = rpx * (750 / 屏幕宽度)
|
|
107
|
-
return value * width / 750
|
|
108
|
-
},
|
|
109
157
|
__getClass (staticClass, dynamicClass) {
|
|
110
158
|
return concat(staticClass, stringifyDynamicClass(dynamicClass))
|
|
111
159
|
},
|
|
112
|
-
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle,
|
|
113
|
-
|
|
114
|
-
const result = []
|
|
160
|
+
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, hide) {
|
|
161
|
+
const result = {}
|
|
115
162
|
const classMap = {}
|
|
116
|
-
|
|
117
|
-
|
|
163
|
+
// todo 全局样式在每个页面和组件中生效,以支持全局原子类,后续支持样式模块复用后可考虑移除
|
|
164
|
+
if (isFunction(global.__getAppClassMap)) {
|
|
165
|
+
Object.assign(classMap, global.__getAppClassMap())
|
|
118
166
|
}
|
|
119
167
|
if (isFunction(this.__getClassMap)) {
|
|
120
168
|
Object.assign(classMap, this.__getClassMap())
|
|
121
169
|
}
|
|
170
|
+
|
|
122
171
|
if (staticClass || dynamicClass) {
|
|
123
|
-
|
|
172
|
+
// todo 当前为了复用小程序unocss产物,暂时进行mpEscape,等后续正式支持unocss后可不进行mpEscape
|
|
173
|
+
const classString = mpEscape(concat(staticClass, stringifyDynamicClass(dynamicClass)))
|
|
124
174
|
classString.split(/\s+/).forEach((className) => {
|
|
125
175
|
if (classMap[className]) {
|
|
126
|
-
|
|
127
|
-
} else if (this.props[className]) {
|
|
128
|
-
// externalClasses
|
|
129
|
-
|
|
176
|
+
Object.assign(result, classMap[className])
|
|
177
|
+
} else if (this.props[className] && isObject(this.props[className])) {
|
|
178
|
+
// externalClasses必定以对象形式传递下来
|
|
179
|
+
Object.assign(result, this.props[className])
|
|
130
180
|
}
|
|
131
181
|
})
|
|
132
182
|
}
|
|
133
183
|
|
|
134
184
|
if (staticStyle || dynamicStyle) {
|
|
135
|
-
const styleObj = Object.assign(parseStyleText(staticStyle), normalizeDynamicStyle(dynamicStyle))
|
|
136
|
-
|
|
185
|
+
const styleObj = Object.assign({}, parseStyleText(staticStyle), normalizeDynamicStyle(dynamicStyle))
|
|
186
|
+
Object.assign(result, transformStyleObj(styleObj))
|
|
137
187
|
}
|
|
138
188
|
|
|
139
|
-
if (
|
|
140
|
-
|
|
189
|
+
if (hide) {
|
|
190
|
+
Object.assign(result, {
|
|
141
191
|
display: 'none'
|
|
142
192
|
})
|
|
143
193
|
}
|
|
@@ -133,7 +133,7 @@ export default function createApp (option, config = {}) {
|
|
|
133
133
|
global.__mpxAppFocusedState.value = `resize${count++}`
|
|
134
134
|
})
|
|
135
135
|
return () => {
|
|
136
|
-
changeSubscription()
|
|
136
|
+
changeSubscription && changeSubscription.remove()
|
|
137
137
|
resizeSubScription && resizeSubScription.remove()
|
|
138
138
|
}
|
|
139
139
|
}, [])
|
|
@@ -58,7 +58,7 @@ export default function createFactory (type) {
|
|
|
58
58
|
// 不接受mixin中的setup配置
|
|
59
59
|
// 注入内建的mixins, 内建mixin是按原始平台编写的,所以合并规则和rootMixins保持一致
|
|
60
60
|
// 将合并后的用户定义的rawOptions传入获取当前应该注入的内建mixins
|
|
61
|
-
rawOptions.mixins = getBuiltInMixins(rawOptions,
|
|
61
|
+
rawOptions.mixins = getBuiltInMixins({ type, rawOptions, currentInject })
|
|
62
62
|
const defaultOptions = getDefaultOptions({ type, rawOptions, currentInject })
|
|
63
63
|
if (__mpx_mode__ === 'web' || __mpx_mode__ === 'ios' || __mpx_mode__ === 'android') {
|
|
64
64
|
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, useMemo, createElement, memo, forwardRef, useImperativeHandle, useContext, createContext, Fragment } from 'react'
|
|
1
|
+
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, useMemo, createElement, memo, forwardRef, useImperativeHandle, useContext, createContext, 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, error, getByPath, collectDataset } from '@mpxjs/utils'
|
|
6
|
+
import { hasOwn, isFunction, noop, isObject, error, getByPath, collectDataset, hump2dash } from '@mpxjs/utils'
|
|
7
7
|
import MpxProxy from '../../../core/proxy'
|
|
8
|
-
import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE } from '../../../core/innerLifecycle'
|
|
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 } from '@mpxjs/api-proxy'
|
|
@@ -24,20 +24,7 @@ function getSystemInfo () {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
function
|
|
28
|
-
const rootProps = {}
|
|
29
|
-
for (const key in props) {
|
|
30
|
-
if (hasOwn(props, key)) {
|
|
31
|
-
const match = /^(bind|catch|capture-bind|capture-catch|style):?(.*?)(?:\.(.*))?$/.exec(key)
|
|
32
|
-
if (match) {
|
|
33
|
-
rootProps[key] = props[key]
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return rootProps
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function createEffect (proxy, components, props) {
|
|
27
|
+
function createEffect (proxy, components) {
|
|
41
28
|
const update = proxy.update = () => {
|
|
42
29
|
// pre render for props update
|
|
43
30
|
if (proxy.propsUpdatedFlag) {
|
|
@@ -57,56 +44,80 @@ function createEffect (proxy, components, props) {
|
|
|
57
44
|
return components[tagName] || getByPath(ReactNative, tagName)
|
|
58
45
|
}
|
|
59
46
|
proxy.effect = new ReactiveEffect(() => {
|
|
60
|
-
|
|
47
|
+
// reset instance
|
|
48
|
+
proxy.target.__resetInstance()
|
|
49
|
+
return proxy.target.__injectedRender(createElement, getComponent)
|
|
61
50
|
}, () => queueJob(update), proxy.scope)
|
|
62
51
|
}
|
|
63
52
|
|
|
64
|
-
function
|
|
53
|
+
function getRootProps (props) {
|
|
54
|
+
const rootProps = {}
|
|
55
|
+
for (const key in props) {
|
|
56
|
+
if (hasOwn(props, key)) {
|
|
57
|
+
const match = /^(bind|catch|capture-bind|capture-catch|style|enable-var):?(.*?)(?:\.(.*))?$/.exec(key)
|
|
58
|
+
if (match) {
|
|
59
|
+
rootProps[key] = props[key]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return rootProps
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function createInstance ({ propsRef, type, rawOptions, currentInject, validProps, components, pageId }) {
|
|
65
67
|
const instance = Object.create({
|
|
66
68
|
setData (data, callback) {
|
|
67
69
|
return this.__mpxProxy.forceUpdate(data, { sync: true }, callback)
|
|
68
70
|
},
|
|
71
|
+
getPageId () {
|
|
72
|
+
return pageId
|
|
73
|
+
},
|
|
69
74
|
__getProps () {
|
|
70
|
-
const propsData = {}
|
|
71
75
|
const props = propsRef.current
|
|
76
|
+
const propsData = {}
|
|
72
77
|
Object.keys(validProps).forEach((key) => {
|
|
73
78
|
if (hasOwn(props, key)) {
|
|
74
79
|
propsData[key] = props[key]
|
|
75
80
|
} else {
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
const altKey = hump2dash(key)
|
|
82
|
+
if (hasOwn(props, altKey)) {
|
|
83
|
+
propsData[key] = props[altKey]
|
|
84
|
+
} else {
|
|
85
|
+
let field = validProps[key]
|
|
86
|
+
if (isFunction(field) || field === null) {
|
|
87
|
+
field = {
|
|
88
|
+
type: field
|
|
89
|
+
}
|
|
80
90
|
}
|
|
91
|
+
// 处理props默认值
|
|
92
|
+
propsData[key] = field.value
|
|
81
93
|
}
|
|
82
|
-
// 处理props默认值
|
|
83
|
-
propsData[key] = field.value
|
|
84
94
|
}
|
|
85
95
|
})
|
|
86
96
|
return propsData
|
|
87
97
|
},
|
|
98
|
+
__resetInstance () {
|
|
99
|
+
this.__refs = {}
|
|
100
|
+
this.__dispatchedSlotSet = new WeakSet()
|
|
101
|
+
},
|
|
88
102
|
__getSlot (name) {
|
|
89
103
|
const { children } = propsRef.current
|
|
90
104
|
if (children) {
|
|
91
105
|
const result = []
|
|
92
106
|
if (Array.isArray(children)) {
|
|
93
107
|
children.forEach(child => {
|
|
94
|
-
if (child
|
|
108
|
+
if (child?.props?.slot === name) {
|
|
95
109
|
result.push(child)
|
|
96
110
|
}
|
|
97
111
|
})
|
|
98
112
|
} else {
|
|
99
|
-
if (children
|
|
113
|
+
if (children?.props?.slot === name) {
|
|
100
114
|
result.push(children)
|
|
101
115
|
}
|
|
102
116
|
}
|
|
103
117
|
return result.filter(item => {
|
|
104
|
-
if (this.__dispatchedSlotSet.has(item))
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
this.__dispatchedSlotSet.add(item)
|
|
108
|
-
return true
|
|
109
|
-
}
|
|
118
|
+
if (!isObject(item) || this.__dispatchedSlotSet.has(item)) return false
|
|
119
|
+
this.__dispatchedSlotSet.add(item)
|
|
120
|
+
return true
|
|
110
121
|
})
|
|
111
122
|
}
|
|
112
123
|
return null
|
|
@@ -204,17 +215,13 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
204
215
|
const proxy = instance.__mpxProxy = new MpxProxy(rawOptions, instance)
|
|
205
216
|
proxy.created()
|
|
206
217
|
|
|
207
|
-
if (type === 'page') {
|
|
208
|
-
proxy.callHook(ONLOAD, [props.route.params || {}])
|
|
209
|
-
}
|
|
210
|
-
|
|
211
218
|
Object.assign(proxy, {
|
|
212
219
|
onStoreChange: null,
|
|
213
220
|
// eslint-disable-next-line symbol-description
|
|
214
221
|
stateVersion: Symbol(),
|
|
215
222
|
subscribe: (onStoreChange) => {
|
|
216
223
|
if (!proxy.effect) {
|
|
217
|
-
createEffect(proxy, components
|
|
224
|
+
createEffect(proxy, components)
|
|
218
225
|
// eslint-disable-next-line symbol-description
|
|
219
226
|
proxy.stateVersion = Symbol()
|
|
220
227
|
}
|
|
@@ -231,7 +238,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
231
238
|
})
|
|
232
239
|
// react数据响应组件更新管理器
|
|
233
240
|
if (!proxy.effect) {
|
|
234
|
-
createEffect(proxy, components
|
|
241
|
+
createEffect(proxy, components)
|
|
235
242
|
}
|
|
236
243
|
|
|
237
244
|
return instance
|
|
@@ -253,7 +260,7 @@ function hasPageHook (mpxProxy, hookNames) {
|
|
|
253
260
|
})
|
|
254
261
|
}
|
|
255
262
|
|
|
256
|
-
const
|
|
263
|
+
const RouteContext = createContext(null)
|
|
257
264
|
|
|
258
265
|
const triggerPageStatusHook = (mpxProxy, event) => {
|
|
259
266
|
mpxProxy.callHook(event === 'show' ? ONSHOW : ONHIDE)
|
|
@@ -277,13 +284,7 @@ const triggerResizeEvent = (mpxProxy) => {
|
|
|
277
284
|
}
|
|
278
285
|
}
|
|
279
286
|
|
|
280
|
-
function
|
|
281
|
-
const { pageId } = useContext(routeContext) || {}
|
|
282
|
-
|
|
283
|
-
instance.getPageId = () => {
|
|
284
|
-
return pageId
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
+
function usePageEffect (mpxProxy, pageId) {
|
|
287
288
|
useEffect(() => {
|
|
288
289
|
let unWatch
|
|
289
290
|
const hasShowHook = hasPageHook(mpxProxy, [ONSHOW, 'show'])
|
|
@@ -300,7 +301,6 @@ function usePageContext (mpxProxy, instance) {
|
|
|
300
301
|
})
|
|
301
302
|
}
|
|
302
303
|
}
|
|
303
|
-
|
|
304
304
|
return () => {
|
|
305
305
|
unWatch && unWatch()
|
|
306
306
|
}
|
|
@@ -343,45 +343,53 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
343
343
|
const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
|
|
344
344
|
const defaultOptions = memo(forwardRef((props, ref) => {
|
|
345
345
|
const instanceRef = useRef(null)
|
|
346
|
-
const propsRef = useRef(
|
|
346
|
+
const propsRef = useRef(null)
|
|
347
|
+
const pageId = useContext(RouteContext)
|
|
348
|
+
propsRef.current = props
|
|
347
349
|
let isFirst = false
|
|
348
350
|
if (!instanceRef.current) {
|
|
349
351
|
isFirst = true
|
|
350
|
-
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components })
|
|
352
|
+
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components, pageId })
|
|
351
353
|
}
|
|
352
354
|
const instance = instanceRef.current
|
|
353
|
-
// reset instance
|
|
354
|
-
instance.__refs = {}
|
|
355
|
-
instance.__dispatchedSlotSet = new WeakSet()
|
|
356
355
|
useImperativeHandle(ref, () => {
|
|
357
356
|
return instance
|
|
358
357
|
})
|
|
359
|
-
const proxy = instance.__mpxProxy
|
|
360
358
|
|
|
361
|
-
|
|
362
|
-
// 处理props更新
|
|
363
|
-
propsRef.current = props
|
|
364
|
-
Object.keys(props).forEach(key => {
|
|
365
|
-
if (hasOwn(validProps, key)) {
|
|
366
|
-
instance[key] = props[key]
|
|
367
|
-
}
|
|
368
|
-
})
|
|
369
|
-
proxy.propsUpdated()
|
|
370
|
-
}
|
|
359
|
+
const proxy = instance.__mpxProxy
|
|
371
360
|
|
|
372
|
-
|
|
361
|
+
proxy.callHook(REACTHOOKSEXEC)
|
|
373
362
|
|
|
374
363
|
useEffect(() => {
|
|
364
|
+
if (!isFirst) {
|
|
365
|
+
// 处理props更新
|
|
366
|
+
Object.keys(validProps).forEach((key) => {
|
|
367
|
+
if (hasOwn(props, key)) {
|
|
368
|
+
instance[key] = props[key]
|
|
369
|
+
} else {
|
|
370
|
+
const altKey = hump2dash(key)
|
|
371
|
+
if (hasOwn(props, altKey)) {
|
|
372
|
+
instance[key] = props[altKey]
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
})
|
|
376
|
+
}
|
|
375
377
|
if (proxy.pendingUpdatedFlag) {
|
|
376
378
|
proxy.pendingUpdatedFlag = false
|
|
377
379
|
proxy.callHook(UPDATED)
|
|
378
380
|
}
|
|
379
381
|
})
|
|
380
382
|
|
|
383
|
+
usePageEffect(proxy, pageId)
|
|
384
|
+
|
|
381
385
|
useEffect(() => {
|
|
386
|
+
if (type === 'page') {
|
|
387
|
+
proxy.callHook(ONLOAD, [props.route.params || {}])
|
|
388
|
+
}
|
|
382
389
|
proxy.mounted()
|
|
383
390
|
return () => {
|
|
384
391
|
proxy.unmounted()
|
|
392
|
+
proxy.target.__resetInstance()
|
|
385
393
|
if (type === 'page') {
|
|
386
394
|
delete global.__mpxPagesMap[props.route.key]
|
|
387
395
|
}
|
|
@@ -390,11 +398,18 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
390
398
|
|
|
391
399
|
useSyncExternalStore(proxy.subscribe, proxy.getSnapshot)
|
|
392
400
|
|
|
393
|
-
|
|
401
|
+
const root = rawOptions.options?.disableMemo ? proxy.effect.run() : useMemo(() => proxy.effect.run(), [proxy.stateVersion])
|
|
402
|
+
if (root) {
|
|
403
|
+
const rootProps = getRootProps(props)
|
|
404
|
+
rootProps.style = { ...root.props.style, ...rootProps.style }
|
|
405
|
+
// update root props
|
|
406
|
+
return cloneElement(root, rootProps)
|
|
407
|
+
}
|
|
408
|
+
return root
|
|
394
409
|
}))
|
|
395
410
|
|
|
396
411
|
if (type === 'page') {
|
|
397
|
-
const { Provider, useSafeAreaInsets } = global.__navigationHelper
|
|
412
|
+
const { Provider, useSafeAreaInsets, GestureHandlerRootView } = global.__navigationHelper
|
|
398
413
|
const pageConfig = Object.assign({}, global.__mpxPageConfig, currentInject.pageConfig)
|
|
399
414
|
const Page = ({ navigation, route }) => {
|
|
400
415
|
const currentPageId = useMemo(() => ++pageId, [])
|
|
@@ -411,31 +426,30 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
411
426
|
})
|
|
412
427
|
}, [])
|
|
413
428
|
|
|
414
|
-
|
|
415
|
-
const safeAreaPadding = {
|
|
416
|
-
paddingTop: insets.top,
|
|
417
|
-
paddingLeft: insets.left
|
|
418
|
-
}
|
|
429
|
+
navigation.insets = useSafeAreaInsets()
|
|
419
430
|
|
|
420
|
-
return createElement(
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
...pageConfig.navigationStyle === 'custom' && safeAreaPadding,
|
|
426
|
-
...ReactNative.StyleSheet.absoluteFillObject,
|
|
427
|
-
backgroundColor: pageConfig.backgroundColor || '#ffffff'
|
|
428
|
-
}
|
|
431
|
+
return createElement(GestureHandlerRootView,
|
|
432
|
+
{
|
|
433
|
+
style: {
|
|
434
|
+
flex: 1,
|
|
435
|
+
backgroundColor: pageConfig.backgroundColor || '#ffffff'
|
|
429
436
|
},
|
|
430
|
-
|
|
437
|
+
onLayout (e) {
|
|
438
|
+
navigation.layout = e.nativeEvent.layout
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
// todo custom portal host for active route
|
|
442
|
+
createElement(Provider,
|
|
443
|
+
null,
|
|
444
|
+
createElement(RouteContext.Provider,
|
|
431
445
|
{
|
|
432
|
-
value:
|
|
446
|
+
value: currentPageId
|
|
433
447
|
},
|
|
434
448
|
createElement(defaultOptions,
|
|
435
449
|
{
|
|
436
450
|
navigation,
|
|
437
451
|
route,
|
|
438
|
-
|
|
452
|
+
id: currentPageId
|
|
439
453
|
}
|
|
440
454
|
)
|
|
441
455
|
)
|
|
@@ -5,7 +5,9 @@ import {
|
|
|
5
5
|
ONSHOW,
|
|
6
6
|
ONHIDE,
|
|
7
7
|
ONLOAD,
|
|
8
|
-
ONRESIZE
|
|
8
|
+
ONRESIZE,
|
|
9
|
+
SERVERPREFETCH,
|
|
10
|
+
REACTHOOKSEXEC
|
|
9
11
|
} from '../../../core/innerLifecycle'
|
|
10
12
|
|
|
11
13
|
const APP_HOOKS = [
|
|
@@ -16,6 +18,7 @@ const APP_HOOKS = [
|
|
|
16
18
|
'onPageNotFound',
|
|
17
19
|
'onUnhandledRejection',
|
|
18
20
|
'onThemeChange',
|
|
21
|
+
'onSSRAppCreated',
|
|
19
22
|
'onAppInit'
|
|
20
23
|
]
|
|
21
24
|
|
|
@@ -43,7 +46,9 @@ const COMPONENT_HOOKS = [
|
|
|
43
46
|
'moved',
|
|
44
47
|
'detached',
|
|
45
48
|
'pageShow',
|
|
46
|
-
'pageHide'
|
|
49
|
+
'pageHide',
|
|
50
|
+
'serverPrefetch',
|
|
51
|
+
'reactHooksExec'
|
|
47
52
|
]
|
|
48
53
|
|
|
49
54
|
export const lifecycleProxyMap = {
|
|
@@ -54,7 +59,9 @@ export const lifecycleProxyMap = {
|
|
|
54
59
|
[ONSHOW]: ['pageShow', 'onShow'],
|
|
55
60
|
[ONHIDE]: ['pageHide', 'onHide'],
|
|
56
61
|
[ONLOAD]: ['onLoad'],
|
|
57
|
-
[ONRESIZE]: ['onResize']
|
|
62
|
+
[ONRESIZE]: ['onResize'],
|
|
63
|
+
[SERVERPREFETCH]: ['serverPrefetch'],
|
|
64
|
+
[REACTHOOKSEXEC]: ['reactHooksExec']
|
|
58
65
|
}
|
|
59
66
|
|
|
60
67
|
export const LIFECYCLE = {
|