@mpxjs/core 2.9.62 → 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 +2 -10
- package/@types/node.d.ts +0 -2
- package/package.json +3 -3
- package/src/convertor/wxToReact.js +1 -1
- package/src/index.js +1 -0
- package/src/platform/builtInMixins/index.js +3 -3
- package/src/platform/builtInMixins/refsMixin.ios.js +25 -48
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +78 -28
- package/src/platform/patch/index.js +1 -1
- package/src/platform/patch/react/getDefaultOptions.ios.js +72 -59
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,7 +32,7 @@ type Data = object | (() => object)
|
|
|
34
32
|
export type PropType<T> = {
|
|
35
33
|
__type: T
|
|
36
34
|
} & (
|
|
37
|
-
T extends
|
|
35
|
+
T extends string
|
|
38
36
|
? StringConstructor
|
|
39
37
|
: T extends number
|
|
40
38
|
? NumberConstructor
|
|
@@ -427,9 +425,7 @@ export interface ComputedRef<T = any> extends WritableComputedRef<T> {
|
|
|
427
425
|
[ComputedRefSymbol]: true
|
|
428
426
|
}
|
|
429
427
|
|
|
430
|
-
export
|
|
431
|
-
// readonly effect: ReactiveEffect<T>
|
|
432
|
-
}
|
|
428
|
+
export type WritableComputedRef<T> = Ref<T>
|
|
433
429
|
|
|
434
430
|
type WatchCallback<T> = (
|
|
435
431
|
value: T,
|
|
@@ -463,7 +459,6 @@ interface EffectScope {
|
|
|
463
459
|
resume (ignoreDirty?: boolean): void
|
|
464
460
|
}
|
|
465
461
|
|
|
466
|
-
|
|
467
462
|
type StringObj = {
|
|
468
463
|
[k: string]: string | StringObj
|
|
469
464
|
}
|
|
@@ -490,7 +485,6 @@ interface UseI18n {
|
|
|
490
485
|
mergeLocaleMessage (locale: string, messages: StringObj): void
|
|
491
486
|
}
|
|
492
487
|
|
|
493
|
-
|
|
494
488
|
export function ref<T extends object> (
|
|
495
489
|
value: T
|
|
496
490
|
): [T] extends [Ref] ? T : Ref<UnwrapRef<T>>
|
|
@@ -530,7 +524,6 @@ export function computed<T> (
|
|
|
530
524
|
options: WritableComputedOptions<T>
|
|
531
525
|
): WritableComputedRef<T>
|
|
532
526
|
|
|
533
|
-
|
|
534
527
|
export function watchEffect (
|
|
535
528
|
effect: (onCleanup: (cleanupFn: () => void) => void) => void,
|
|
536
529
|
options?: WatchEffectOptions
|
|
@@ -546,7 +539,6 @@ export function watchPostEffect (
|
|
|
546
539
|
options?: WatchEffectOptions
|
|
547
540
|
): void
|
|
548
541
|
|
|
549
|
-
|
|
550
542
|
export function watch<T extends MultiWatchSources> (
|
|
551
543
|
sources: [...T],
|
|
552
544
|
callback: WatchCallback<{
|
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
|
},
|
|
@@ -93,5 +93,5 @@
|
|
|
93
93
|
"url": "https://github.com/didi/mpx/issues"
|
|
94
94
|
},
|
|
95
95
|
"sideEffects": false,
|
|
96
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "803334dc0e600f219d514c27461aa7663b7a6653"
|
|
97
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)
|
package/src/index.js
CHANGED
|
@@ -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,78 +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
|
-
})
|
|
41
|
-
refs.forEach(({ key, type, all, sKeys }) => {
|
|
42
|
-
// 如果没有 sKey 说明使用的是 wx:ref="xxx" 的场景
|
|
43
|
-
if (!sKeys) {
|
|
44
|
-
Object.defineProperty(this.$refs, key, {
|
|
45
|
-
enumerable: true,
|
|
46
|
-
configurable: true,
|
|
47
|
-
get () {
|
|
48
|
-
const refs = target.__refs[key] || []
|
|
49
|
-
if (type === 'component') {
|
|
50
|
-
return all ? refs : refs[0]
|
|
51
|
-
} else {
|
|
52
|
-
return createSelectorQuery().in(target).select(key, all)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
27
|
})
|
|
58
28
|
},
|
|
59
|
-
__getRefVal (
|
|
29
|
+
__getRefVal (type, selectorsConf) {
|
|
60
30
|
return (instance) => {
|
|
61
31
|
if (instance) {
|
|
62
|
-
|
|
63
|
-
|
|
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
|
+
})
|
|
40
|
+
}
|
|
41
|
+
})
|
|
64
42
|
}
|
|
65
43
|
}
|
|
66
44
|
},
|
|
67
45
|
__selectRef (selector, refType, all = false) {
|
|
68
46
|
const splitedSelector = selector.match(/(#|\.)?[^.#]+/g) || []
|
|
69
47
|
const refsArr = splitedSelector.map(selector => {
|
|
70
|
-
const
|
|
48
|
+
const refs = this.__refs[selector] || []
|
|
71
49
|
const res = []
|
|
72
|
-
|
|
50
|
+
refs.forEach(({ type, instance }) => {
|
|
73
51
|
if (type === refType) {
|
|
74
|
-
|
|
75
|
-
res.push(..._refs)
|
|
52
|
+
res.push(instance)
|
|
76
53
|
}
|
|
77
54
|
})
|
|
78
55
|
return res
|
|
@@ -1,5 +1,56 @@
|
|
|
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
|
+
|
|
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
|
+
})
|
|
3
54
|
|
|
4
55
|
function concat (a = '', b = '') {
|
|
5
56
|
return a ? b ? (a + ' ' + b) : a : b
|
|
@@ -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,48 +133,44 @@ 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
|
-
// todo 每次返回新对象会导致react memo优化失效,需要考虑优化手段
|
|
160
|
+
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, hide) {
|
|
114
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
176
|
Object.assign(result, classMap[className])
|
|
@@ -132,11 +182,11 @@ export default function styleHelperMixin (type) {
|
|
|
132
182
|
}
|
|
133
183
|
|
|
134
184
|
if (staticStyle || dynamicStyle) {
|
|
135
|
-
const styleObj = Object.assign(parseStyleText(staticStyle), normalizeDynamicStyle(dynamicStyle))
|
|
136
|
-
Object.assign(result, transformStyleObj(
|
|
185
|
+
const styleObj = Object.assign({}, parseStyleText(staticStyle), normalizeDynamicStyle(dynamicStyle))
|
|
186
|
+
Object.assign(result, transformStyleObj(styleObj))
|
|
137
187
|
}
|
|
138
188
|
|
|
139
|
-
if (
|
|
189
|
+
if (hide) {
|
|
140
190
|
Object.assign(result, {
|
|
141
191
|
display: 'none'
|
|
142
192
|
})
|
|
@@ -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,9 +1,9 @@
|
|
|
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
8
|
import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE, REACTHOOKSEXEC } from '../../../core/innerLifecycle'
|
|
9
9
|
import mergeOptions from '../../../core/mergeOptions'
|
|
@@ -46,15 +46,31 @@ function createEffect (proxy, components) {
|
|
|
46
46
|
proxy.effect = new ReactiveEffect(() => {
|
|
47
47
|
// reset instance
|
|
48
48
|
proxy.target.__resetInstance()
|
|
49
|
-
return proxy.target.__injectedRender(createElement, getComponent
|
|
49
|
+
return proxy.target.__injectedRender(createElement, getComponent)
|
|
50
50
|
}, () => queueJob(update), proxy.scope)
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
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 }) {
|
|
54
67
|
const instance = Object.create({
|
|
55
68
|
setData (data, callback) {
|
|
56
69
|
return this.__mpxProxy.forceUpdate(data, { sync: true }, callback)
|
|
57
70
|
},
|
|
71
|
+
getPageId () {
|
|
72
|
+
return pageId
|
|
73
|
+
},
|
|
58
74
|
__getProps () {
|
|
59
75
|
const props = propsRef.current
|
|
60
76
|
const propsData = {}
|
|
@@ -62,31 +78,23 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
62
78
|
if (hasOwn(props, key)) {
|
|
63
79
|
propsData[key] = props[key]
|
|
64
80
|
} else {
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
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
|
+
}
|
|
69
90
|
}
|
|
91
|
+
// 处理props默认值
|
|
92
|
+
propsData[key] = field.value
|
|
70
93
|
}
|
|
71
|
-
// 处理props默认值
|
|
72
|
-
propsData[key] = field.value
|
|
73
94
|
}
|
|
74
95
|
})
|
|
75
96
|
return propsData
|
|
76
97
|
},
|
|
77
|
-
__getRootProps () {
|
|
78
|
-
const props = propsRef.current
|
|
79
|
-
const rootProps = {}
|
|
80
|
-
for (const key in props) {
|
|
81
|
-
if (hasOwn(props, key)) {
|
|
82
|
-
const match = /^(bind|catch|capture-bind|capture-catch|style):?(.*?)(?:\.(.*))?$/.exec(key)
|
|
83
|
-
if (match) {
|
|
84
|
-
rootProps[key] = props[key]
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return rootProps
|
|
89
|
-
},
|
|
90
98
|
__resetInstance () {
|
|
91
99
|
this.__refs = {}
|
|
92
100
|
this.__dispatchedSlotSet = new WeakSet()
|
|
@@ -97,22 +105,19 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
97
105
|
const result = []
|
|
98
106
|
if (Array.isArray(children)) {
|
|
99
107
|
children.forEach(child => {
|
|
100
|
-
if (child
|
|
108
|
+
if (child?.props?.slot === name) {
|
|
101
109
|
result.push(child)
|
|
102
110
|
}
|
|
103
111
|
})
|
|
104
112
|
} else {
|
|
105
|
-
if (children
|
|
113
|
+
if (children?.props?.slot === name) {
|
|
106
114
|
result.push(children)
|
|
107
115
|
}
|
|
108
116
|
}
|
|
109
117
|
return result.filter(item => {
|
|
110
|
-
if (this.__dispatchedSlotSet.has(item))
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this.__dispatchedSlotSet.add(item)
|
|
114
|
-
return true
|
|
115
|
-
}
|
|
118
|
+
if (!isObject(item) || this.__dispatchedSlotSet.has(item)) return false
|
|
119
|
+
this.__dispatchedSlotSet.add(item)
|
|
120
|
+
return true
|
|
116
121
|
})
|
|
117
122
|
}
|
|
118
123
|
return null
|
|
@@ -255,7 +260,7 @@ function hasPageHook (mpxProxy, hookNames) {
|
|
|
255
260
|
})
|
|
256
261
|
}
|
|
257
262
|
|
|
258
|
-
const
|
|
263
|
+
const RouteContext = createContext(null)
|
|
259
264
|
|
|
260
265
|
const triggerPageStatusHook = (mpxProxy, event) => {
|
|
261
266
|
mpxProxy.callHook(event === 'show' ? ONSHOW : ONHIDE)
|
|
@@ -279,13 +284,7 @@ const triggerResizeEvent = (mpxProxy) => {
|
|
|
279
284
|
}
|
|
280
285
|
}
|
|
281
286
|
|
|
282
|
-
function
|
|
283
|
-
const { pageId } = useContext(routeContext) || {}
|
|
284
|
-
|
|
285
|
-
instance.getPageId = () => {
|
|
286
|
-
return pageId
|
|
287
|
-
}
|
|
288
|
-
|
|
287
|
+
function usePageEffect (mpxProxy, pageId) {
|
|
289
288
|
useEffect(() => {
|
|
290
289
|
let unWatch
|
|
291
290
|
const hasShowHook = hasPageHook(mpxProxy, [ONSHOW, 'show'])
|
|
@@ -302,7 +301,6 @@ function usePageContext (mpxProxy, instance) {
|
|
|
302
301
|
})
|
|
303
302
|
}
|
|
304
303
|
}
|
|
305
|
-
|
|
306
304
|
return () => {
|
|
307
305
|
unWatch && unWatch()
|
|
308
306
|
}
|
|
@@ -346,11 +344,12 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
346
344
|
const defaultOptions = memo(forwardRef((props, ref) => {
|
|
347
345
|
const instanceRef = useRef(null)
|
|
348
346
|
const propsRef = useRef(null)
|
|
347
|
+
const pageId = useContext(RouteContext)
|
|
349
348
|
propsRef.current = props
|
|
350
349
|
let isFirst = false
|
|
351
350
|
if (!instanceRef.current) {
|
|
352
351
|
isFirst = true
|
|
353
|
-
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components })
|
|
352
|
+
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components, pageId })
|
|
354
353
|
}
|
|
355
354
|
const instance = instanceRef.current
|
|
356
355
|
useImperativeHandle(ref, () => {
|
|
@@ -364,9 +363,14 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
364
363
|
useEffect(() => {
|
|
365
364
|
if (!isFirst) {
|
|
366
365
|
// 处理props更新
|
|
367
|
-
Object.keys(
|
|
368
|
-
if (hasOwn(
|
|
366
|
+
Object.keys(validProps).forEach((key) => {
|
|
367
|
+
if (hasOwn(props, key)) {
|
|
369
368
|
instance[key] = props[key]
|
|
369
|
+
} else {
|
|
370
|
+
const altKey = hump2dash(key)
|
|
371
|
+
if (hasOwn(props, altKey)) {
|
|
372
|
+
instance[key] = props[altKey]
|
|
373
|
+
}
|
|
370
374
|
}
|
|
371
375
|
})
|
|
372
376
|
}
|
|
@@ -376,7 +380,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
376
380
|
}
|
|
377
381
|
})
|
|
378
382
|
|
|
379
|
-
|
|
383
|
+
usePageEffect(proxy, pageId)
|
|
380
384
|
|
|
381
385
|
useEffect(() => {
|
|
382
386
|
if (type === 'page') {
|
|
@@ -385,6 +389,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
385
389
|
proxy.mounted()
|
|
386
390
|
return () => {
|
|
387
391
|
proxy.unmounted()
|
|
392
|
+
proxy.target.__resetInstance()
|
|
388
393
|
if (type === 'page') {
|
|
389
394
|
delete global.__mpxPagesMap[props.route.key]
|
|
390
395
|
}
|
|
@@ -393,7 +398,14 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
393
398
|
|
|
394
399
|
useSyncExternalStore(proxy.subscribe, proxy.getSnapshot)
|
|
395
400
|
|
|
396
|
-
|
|
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
|
|
397
409
|
}))
|
|
398
410
|
|
|
399
411
|
if (type === 'page') {
|
|
@@ -416,27 +428,28 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
416
428
|
|
|
417
429
|
navigation.insets = useSafeAreaInsets()
|
|
418
430
|
|
|
419
|
-
return createElement(
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
flex: 1,
|
|
425
|
-
backgroundColor: pageConfig.backgroundColor || '#ffffff'
|
|
426
|
-
},
|
|
427
|
-
onLayout (e) {
|
|
428
|
-
navigation.layout = e.nativeEvent.layout
|
|
429
|
-
}
|
|
431
|
+
return createElement(GestureHandlerRootView,
|
|
432
|
+
{
|
|
433
|
+
style: {
|
|
434
|
+
flex: 1,
|
|
435
|
+
backgroundColor: pageConfig.backgroundColor || '#ffffff'
|
|
430
436
|
},
|
|
431
|
-
|
|
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,
|
|
432
445
|
{
|
|
433
|
-
value:
|
|
446
|
+
value: currentPageId
|
|
434
447
|
},
|
|
435
448
|
createElement(defaultOptions,
|
|
436
449
|
{
|
|
437
450
|
navigation,
|
|
438
451
|
route,
|
|
439
|
-
|
|
452
|
+
id: currentPageId
|
|
440
453
|
}
|
|
441
454
|
)
|
|
442
455
|
)
|