@mpxjs/core 2.9.62 → 2.9.65
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 +4 -12
- package/@types/node.d.ts +0 -2
- package/package.json +7 -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/pageScrollMixin.web.js +8 -10
- package/src/platform/builtInMixins/refsMixin.ios.js +25 -48
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +89 -35
- package/src/platform/patch/index.js +1 -1
- package/src/platform/patch/react/getDefaultOptions.ios.js +97 -61
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
|
|
@@ -116,7 +114,7 @@ interface Context {
|
|
|
116
114
|
refs: ObjectOf<WechatMiniprogram.NodesRef & ComponentIns<{}, {}, {}, {}, []>>
|
|
117
115
|
asyncRefs: ObjectOf<Promise<WechatMiniprogram.NodesRef & ComponentIns<{}, {}, {}, {}, []>>>
|
|
118
116
|
|
|
119
|
-
forceUpdate (params?: object, callback?: () => void): void
|
|
117
|
+
forceUpdate (params?: object, options?: object | (() => void), callback?: () => void): void
|
|
120
118
|
|
|
121
119
|
selectComponent: ReplaceWxComponentIns['selectComponent']
|
|
122
120
|
selectAllComponents: ReplaceWxComponentIns['selectAllComponents']
|
|
@@ -185,7 +183,7 @@ export interface MpxComponentIns {
|
|
|
185
183
|
|
|
186
184
|
$watch (expr: string | (() => any), handler: WatchHandler | WatchOptWithHandler, options?: WatchOpt): () => void
|
|
187
185
|
|
|
188
|
-
$forceUpdate (params?: object, callback?: () => void): void
|
|
186
|
+
$forceUpdate (params?: object, options?: object | (() => void), callback?: () => void): void
|
|
189
187
|
|
|
190
188
|
$nextTick (fn: () => void): void
|
|
191
189
|
|
|
@@ -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.65",
|
|
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.65",
|
|
23
23
|
"lodash": "^4.1.1",
|
|
24
24
|
"miniprogram-api-typings": "^3.10.0"
|
|
25
25
|
},
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"react": "*",
|
|
33
33
|
"react-native": "*",
|
|
34
34
|
"react-native-gesture-handler": "^2.19.0",
|
|
35
|
+
"react-native-linear-gradient": "^2.8.3",
|
|
35
36
|
"react-native-safe-area-context": "^4.10.1",
|
|
36
37
|
"react-native-webview": "^13.10.5",
|
|
37
38
|
"vue": "^2.7.10",
|
|
@@ -75,6 +76,9 @@
|
|
|
75
76
|
},
|
|
76
77
|
"react-native-gesture-handler": {
|
|
77
78
|
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"react-native-linear-gradient": {
|
|
81
|
+
"optional": true
|
|
78
82
|
}
|
|
79
83
|
},
|
|
80
84
|
"publishConfig": {
|
|
@@ -93,5 +97,5 @@
|
|
|
93
97
|
"url": "https://github.com/didi/mpx/issues"
|
|
94
98
|
},
|
|
95
99
|
"sideEffects": false,
|
|
96
|
-
"gitHead": "
|
|
100
|
+
"gitHead": "24efa90e90b4d42c285ca61739cb9e4d0696976c"
|
|
97
101
|
}
|
|
@@ -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),
|
|
@@ -14,23 +14,21 @@ function refreshMs () {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
let loading = null
|
|
18
|
-
|
|
19
17
|
function showLoading (vm) {
|
|
20
18
|
const { backgroundColor = 'transparent', backgroundTextStyle = 'dark' } = vm.$options.__mpxPageConfig
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
vm.__mpxloading = document.createElement('div')
|
|
20
|
+
vm.__mpxloading.className = 'pull-down-loading'
|
|
21
|
+
vm.__mpxloading.style.cssText = `background-color: ${backgroundColor};`
|
|
24
22
|
const dot = document.createElement('div')
|
|
25
23
|
dot.className = `dot-flashing ${backgroundTextStyle}`
|
|
26
|
-
|
|
27
|
-
vm.$el.prepend(
|
|
24
|
+
vm.__mpxloading.append(dot)
|
|
25
|
+
vm.$el.prepend(vm.__mpxloading)
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
function hideLoading (vm) {
|
|
31
|
-
if (
|
|
32
|
-
vm.$el.removeChild(
|
|
33
|
-
|
|
29
|
+
if (vm.__mpxloading) {
|
|
30
|
+
vm.$el.removeChild(vm.__mpxloading)
|
|
31
|
+
vm.__mpxloading = null
|
|
34
32
|
}
|
|
35
33
|
}
|
|
36
34
|
|
|
@@ -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,69 @@
|
|
|
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
|
+
const unit = {
|
|
20
|
+
rpx,
|
|
21
|
+
vw,
|
|
22
|
+
vh
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function formatValue (value) {
|
|
26
|
+
let matched
|
|
27
|
+
if ((matched = numberRegExp.exec(value))) {
|
|
28
|
+
value = +matched[1]
|
|
29
|
+
} else if ((matched = unitRegExp.exec(value))) {
|
|
30
|
+
value = unit[matched[2]](+matched[1])
|
|
31
|
+
} else if (hairlineRegExp.test(value)) {
|
|
32
|
+
value = StyleSheet.hairlineWidth
|
|
33
|
+
}
|
|
34
|
+
return value
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
global.__formatValue = formatValue
|
|
38
|
+
|
|
39
|
+
const escapeReg = /[()[\]{}#!.:,%'"+$]/g
|
|
40
|
+
const escapeMap = {
|
|
41
|
+
'(': '_pl_',
|
|
42
|
+
')': '_pr_',
|
|
43
|
+
'[': '_bl_',
|
|
44
|
+
']': '_br_',
|
|
45
|
+
'{': '_cl_',
|
|
46
|
+
'}': '_cr_',
|
|
47
|
+
'#': '_h_',
|
|
48
|
+
'!': '_i_',
|
|
49
|
+
'/': '_s_',
|
|
50
|
+
'.': '_d_',
|
|
51
|
+
':': '_c_',
|
|
52
|
+
',': '_2c_',
|
|
53
|
+
'%': '_p_',
|
|
54
|
+
'\'': '_q_',
|
|
55
|
+
'"': '_dq_',
|
|
56
|
+
'+': '_a_',
|
|
57
|
+
$: '_si_'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const mpEscape = cached((str) => {
|
|
61
|
+
return str.replace(escapeReg, function (match) {
|
|
62
|
+
if (escapeMap[match]) return escapeMap[match]
|
|
63
|
+
// unknown escaped
|
|
64
|
+
return '_u_'
|
|
65
|
+
})
|
|
66
|
+
})
|
|
3
67
|
|
|
4
68
|
function concat (a = '', b = '') {
|
|
5
69
|
return a ? b ? (a + ' ' + b) : a : b
|
|
@@ -41,10 +105,13 @@ function stringifyDynamicClass (value) {
|
|
|
41
105
|
|
|
42
106
|
const listDelimiter = /;(?![^(]*[)])/g
|
|
43
107
|
const propertyDelimiter = /:(.+)/
|
|
44
|
-
const
|
|
45
|
-
const
|
|
108
|
+
const unitRegExp = /^\s*(-?\d+(?:\.\d+)?)(rpx|vw|vh)\s*$/
|
|
109
|
+
const numberRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/
|
|
110
|
+
const hairlineRegExp = /^\s*hairlineWidth\s*$/
|
|
111
|
+
const varRegExp = /^--/
|
|
46
112
|
|
|
47
|
-
|
|
113
|
+
const parseStyleText = cached((cssText) => {
|
|
114
|
+
if (typeof cssText !== 'string') return cssText
|
|
48
115
|
const res = {}
|
|
49
116
|
const arr = cssText.split(listDelimiter)
|
|
50
117
|
for (let i = 0; i < arr.length; i++) {
|
|
@@ -52,13 +119,14 @@ function parseStyleText (cssText = '') {
|
|
|
52
119
|
if (item) {
|
|
53
120
|
const tmp = item.split(propertyDelimiter)
|
|
54
121
|
if (tmp.length > 1) {
|
|
55
|
-
|
|
122
|
+
let k = tmp[0].trim()
|
|
123
|
+
k = varRegExp.test(k) ? k : dash2hump(k)
|
|
56
124
|
res[k] = tmp[1].trim()
|
|
57
125
|
}
|
|
58
126
|
}
|
|
59
127
|
}
|
|
60
128
|
return res
|
|
61
|
-
}
|
|
129
|
+
})
|
|
62
130
|
|
|
63
131
|
function normalizeDynamicStyle (value) {
|
|
64
132
|
if (!value) return {}
|
|
@@ -79,48 +147,34 @@ function mergeObjectArray (arr) {
|
|
|
79
147
|
return res
|
|
80
148
|
}
|
|
81
149
|
|
|
82
|
-
function transformStyleObj (
|
|
83
|
-
const keys = Object.keys(styleObj)
|
|
150
|
+
function transformStyleObj (styleObj) {
|
|
84
151
|
const transformed = {}
|
|
85
|
-
keys.forEach((prop) => {
|
|
86
|
-
|
|
87
|
-
let value = styleObj[prop]
|
|
88
|
-
let matched
|
|
89
|
-
if ((matched = pxRegExp.exec(value))) {
|
|
90
|
-
value = +matched[1]
|
|
91
|
-
} else if ((matched = rpxRegExp.exec(value))) {
|
|
92
|
-
value = context.__rpx(+matched[1])
|
|
93
|
-
}
|
|
94
|
-
// todo 检测不支持的value
|
|
95
|
-
transformed[prop] = value
|
|
152
|
+
Object.keys(styleObj).forEach((prop) => {
|
|
153
|
+
transformed[prop] = formatValue(styleObj[prop])
|
|
96
154
|
})
|
|
97
155
|
return transformed
|
|
98
156
|
}
|
|
99
157
|
|
|
100
|
-
export default function styleHelperMixin (
|
|
158
|
+
export default function styleHelperMixin () {
|
|
101
159
|
return {
|
|
102
160
|
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
161
|
__getClass (staticClass, dynamicClass) {
|
|
110
162
|
return concat(staticClass, stringifyDynamicClass(dynamicClass))
|
|
111
163
|
},
|
|
112
|
-
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle,
|
|
113
|
-
// todo 每次返回新对象会导致react memo优化失效,需要考虑优化手段
|
|
164
|
+
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, hide) {
|
|
114
165
|
const result = {}
|
|
115
166
|
const classMap = {}
|
|
116
|
-
|
|
117
|
-
|
|
167
|
+
// todo 全局样式在每个页面和组件中生效,以支持全局原子类,后续支持样式模块复用后可考虑移除
|
|
168
|
+
if (isFunction(global.__getAppClassMap)) {
|
|
169
|
+
Object.assign(classMap, global.__getAppClassMap())
|
|
118
170
|
}
|
|
119
171
|
if (isFunction(this.__getClassMap)) {
|
|
120
172
|
Object.assign(classMap, this.__getClassMap())
|
|
121
173
|
}
|
|
174
|
+
|
|
122
175
|
if (staticClass || dynamicClass) {
|
|
123
|
-
|
|
176
|
+
// todo 当前为了复用小程序unocss产物,暂时进行mpEscape,等后续正式支持unocss后可不进行mpEscape
|
|
177
|
+
const classString = mpEscape(concat(staticClass, stringifyDynamicClass(dynamicClass)))
|
|
124
178
|
classString.split(/\s+/).forEach((className) => {
|
|
125
179
|
if (classMap[className]) {
|
|
126
180
|
Object.assign(result, classMap[className])
|
|
@@ -132,11 +186,11 @@ export default function styleHelperMixin (type) {
|
|
|
132
186
|
}
|
|
133
187
|
|
|
134
188
|
if (staticStyle || dynamicStyle) {
|
|
135
|
-
const styleObj = Object.assign(parseStyleText(staticStyle), normalizeDynamicStyle(dynamicStyle))
|
|
136
|
-
Object.assign(result, transformStyleObj(
|
|
189
|
+
const styleObj = Object.assign({}, parseStyleText(staticStyle), normalizeDynamicStyle(dynamicStyle))
|
|
190
|
+
Object.assign(result, transformStyleObj(styleObj))
|
|
137
191
|
}
|
|
138
192
|
|
|
139
|
-
if (
|
|
193
|
+
if (hide) {
|
|
140
194
|
Object.assign(result, {
|
|
141
195
|
display: 'none'
|
|
142
196
|
})
|
|
@@ -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'
|
|
@@ -40,21 +40,42 @@ function createEffect (proxy, components) {
|
|
|
40
40
|
}
|
|
41
41
|
update.id = proxy.uid
|
|
42
42
|
const getComponent = (tagName) => {
|
|
43
|
+
if (!tagName) return null
|
|
43
44
|
if (tagName === 'block') return Fragment
|
|
44
45
|
return components[tagName] || getByPath(ReactNative, tagName)
|
|
45
46
|
}
|
|
47
|
+
const innerCreateElement = (type, ...rest) => {
|
|
48
|
+
if (!type) return null
|
|
49
|
+
return createElement(type, ...rest)
|
|
50
|
+
}
|
|
46
51
|
proxy.effect = new ReactiveEffect(() => {
|
|
47
52
|
// reset instance
|
|
48
53
|
proxy.target.__resetInstance()
|
|
49
|
-
return proxy.target.__injectedRender(
|
|
54
|
+
return proxy.target.__injectedRender(innerCreateElement, getComponent)
|
|
50
55
|
}, () => queueJob(update), proxy.scope)
|
|
51
56
|
}
|
|
52
57
|
|
|
53
|
-
function
|
|
58
|
+
function getRootProps (props) {
|
|
59
|
+
const rootProps = {}
|
|
60
|
+
for (const key in props) {
|
|
61
|
+
if (hasOwn(props, key)) {
|
|
62
|
+
const match = /^(bind|catch|capture-bind|capture-catch|style|enable-var):?(.*?)(?:\.(.*))?$/.exec(key)
|
|
63
|
+
if (match) {
|
|
64
|
+
rootProps[key] = props[key]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return rootProps
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function createInstance ({ propsRef, type, rawOptions, currentInject, validProps, components, pageId }) {
|
|
54
72
|
const instance = Object.create({
|
|
55
73
|
setData (data, callback) {
|
|
56
74
|
return this.__mpxProxy.forceUpdate(data, { sync: true }, callback)
|
|
57
75
|
},
|
|
76
|
+
getPageId () {
|
|
77
|
+
return pageId
|
|
78
|
+
},
|
|
58
79
|
__getProps () {
|
|
59
80
|
const props = propsRef.current
|
|
60
81
|
const propsData = {}
|
|
@@ -62,31 +83,23 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
62
83
|
if (hasOwn(props, key)) {
|
|
63
84
|
propsData[key] = props[key]
|
|
64
85
|
} else {
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
const altKey = hump2dash(key)
|
|
87
|
+
if (hasOwn(props, altKey)) {
|
|
88
|
+
propsData[key] = props[altKey]
|
|
89
|
+
} else {
|
|
90
|
+
let field = validProps[key]
|
|
91
|
+
if (isFunction(field) || field === null) {
|
|
92
|
+
field = {
|
|
93
|
+
type: field
|
|
94
|
+
}
|
|
69
95
|
}
|
|
96
|
+
// 处理props默认值
|
|
97
|
+
propsData[key] = field.value
|
|
70
98
|
}
|
|
71
|
-
// 处理props默认值
|
|
72
|
-
propsData[key] = field.value
|
|
73
99
|
}
|
|
74
100
|
})
|
|
75
101
|
return propsData
|
|
76
102
|
},
|
|
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
103
|
__resetInstance () {
|
|
91
104
|
this.__refs = {}
|
|
92
105
|
this.__dispatchedSlotSet = new WeakSet()
|
|
@@ -97,22 +110,19 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
97
110
|
const result = []
|
|
98
111
|
if (Array.isArray(children)) {
|
|
99
112
|
children.forEach(child => {
|
|
100
|
-
if (child
|
|
113
|
+
if (child?.props?.slot === name) {
|
|
101
114
|
result.push(child)
|
|
102
115
|
}
|
|
103
116
|
})
|
|
104
117
|
} else {
|
|
105
|
-
if (children
|
|
118
|
+
if (children?.props?.slot === name) {
|
|
106
119
|
result.push(children)
|
|
107
120
|
}
|
|
108
121
|
}
|
|
109
122
|
return result.filter(item => {
|
|
110
|
-
if (this.__dispatchedSlotSet.has(item))
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this.__dispatchedSlotSet.add(item)
|
|
114
|
-
return true
|
|
115
|
-
}
|
|
123
|
+
if (!isObject(item) || this.__dispatchedSlotSet.has(item)) return false
|
|
124
|
+
this.__dispatchedSlotSet.add(item)
|
|
125
|
+
return true
|
|
116
126
|
})
|
|
117
127
|
}
|
|
118
128
|
return null
|
|
@@ -255,7 +265,7 @@ function hasPageHook (mpxProxy, hookNames) {
|
|
|
255
265
|
})
|
|
256
266
|
}
|
|
257
267
|
|
|
258
|
-
const
|
|
268
|
+
const RouteContext = createContext(null)
|
|
259
269
|
|
|
260
270
|
const triggerPageStatusHook = (mpxProxy, event) => {
|
|
261
271
|
mpxProxy.callHook(event === 'show' ? ONSHOW : ONHIDE)
|
|
@@ -279,13 +289,7 @@ const triggerResizeEvent = (mpxProxy) => {
|
|
|
279
289
|
}
|
|
280
290
|
}
|
|
281
291
|
|
|
282
|
-
function
|
|
283
|
-
const { pageId } = useContext(routeContext) || {}
|
|
284
|
-
|
|
285
|
-
instance.getPageId = () => {
|
|
286
|
-
return pageId
|
|
287
|
-
}
|
|
288
|
-
|
|
292
|
+
function usePageEffect (mpxProxy, pageId) {
|
|
289
293
|
useEffect(() => {
|
|
290
294
|
let unWatch
|
|
291
295
|
const hasShowHook = hasPageHook(mpxProxy, [ONSHOW, 'show'])
|
|
@@ -302,7 +306,6 @@ function usePageContext (mpxProxy, instance) {
|
|
|
302
306
|
})
|
|
303
307
|
}
|
|
304
308
|
}
|
|
305
|
-
|
|
306
309
|
return () => {
|
|
307
310
|
unWatch && unWatch()
|
|
308
311
|
}
|
|
@@ -346,11 +349,12 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
346
349
|
const defaultOptions = memo(forwardRef((props, ref) => {
|
|
347
350
|
const instanceRef = useRef(null)
|
|
348
351
|
const propsRef = useRef(null)
|
|
352
|
+
const pageId = useContext(RouteContext)
|
|
349
353
|
propsRef.current = props
|
|
350
354
|
let isFirst = false
|
|
351
355
|
if (!instanceRef.current) {
|
|
352
356
|
isFirst = true
|
|
353
|
-
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components })
|
|
357
|
+
instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components, pageId })
|
|
354
358
|
}
|
|
355
359
|
const instance = instanceRef.current
|
|
356
360
|
useImperativeHandle(ref, () => {
|
|
@@ -364,9 +368,14 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
364
368
|
useEffect(() => {
|
|
365
369
|
if (!isFirst) {
|
|
366
370
|
// 处理props更新
|
|
367
|
-
Object.keys(
|
|
368
|
-
if (hasOwn(
|
|
371
|
+
Object.keys(validProps).forEach((key) => {
|
|
372
|
+
if (hasOwn(props, key)) {
|
|
369
373
|
instance[key] = props[key]
|
|
374
|
+
} else {
|
|
375
|
+
const altKey = hump2dash(key)
|
|
376
|
+
if (hasOwn(props, altKey)) {
|
|
377
|
+
instance[key] = props[altKey]
|
|
378
|
+
}
|
|
370
379
|
}
|
|
371
380
|
})
|
|
372
381
|
}
|
|
@@ -376,7 +385,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
376
385
|
}
|
|
377
386
|
})
|
|
378
387
|
|
|
379
|
-
|
|
388
|
+
usePageEffect(proxy, pageId)
|
|
380
389
|
|
|
381
390
|
useEffect(() => {
|
|
382
391
|
if (type === 'page') {
|
|
@@ -385,6 +394,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
385
394
|
proxy.mounted()
|
|
386
395
|
return () => {
|
|
387
396
|
proxy.unmounted()
|
|
397
|
+
proxy.target.__resetInstance()
|
|
388
398
|
if (type === 'page') {
|
|
389
399
|
delete global.__mpxPagesMap[props.route.key]
|
|
390
400
|
}
|
|
@@ -393,50 +403,76 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
393
403
|
|
|
394
404
|
useSyncExternalStore(proxy.subscribe, proxy.getSnapshot)
|
|
395
405
|
|
|
396
|
-
|
|
406
|
+
const root = rawOptions.options?.disableMemo ? proxy.effect.run() : useMemo(() => proxy.effect.run(), [proxy.stateVersion])
|
|
407
|
+
if (root) {
|
|
408
|
+
const rootProps = getRootProps(props)
|
|
409
|
+
rootProps.style = { ...root.props.style, ...rootProps.style }
|
|
410
|
+
// update root props
|
|
411
|
+
return cloneElement(root, rootProps)
|
|
412
|
+
}
|
|
413
|
+
return root
|
|
397
414
|
}))
|
|
398
415
|
|
|
399
416
|
if (type === 'page') {
|
|
400
417
|
const { Provider, useSafeAreaInsets, GestureHandlerRootView } = global.__navigationHelper
|
|
401
418
|
const pageConfig = Object.assign({}, global.__mpxPageConfig, currentInject.pageConfig)
|
|
402
419
|
const Page = ({ navigation, route }) => {
|
|
420
|
+
const rootRef = useRef(null)
|
|
403
421
|
const currentPageId = useMemo(() => ++pageId, [])
|
|
404
422
|
usePageStatus(navigation, currentPageId)
|
|
405
423
|
|
|
406
424
|
useLayoutEffect(() => {
|
|
425
|
+
rootRef.current?.measureInWindow((x, y, width, height) => {
|
|
426
|
+
navigation.layout = { x, y, width, height }
|
|
427
|
+
})
|
|
428
|
+
const isCustom = pageConfig.navigationStyle === 'custom'
|
|
429
|
+
let opt = {}
|
|
430
|
+
if (__mpx_mode__ === 'android') {
|
|
431
|
+
opt = {
|
|
432
|
+
statusBarTranslucent: isCustom,
|
|
433
|
+
statusBarStyle: pageConfig.statusBarStyle, // 枚举值 'auto' | 'dark' | 'light' 控制statusbar字体颜色
|
|
434
|
+
statusBarColor: isCustom ? 'transparent' : pageConfig.statusBarColor // 控制statusbar背景颜色
|
|
435
|
+
}
|
|
436
|
+
} else if (__mpx_mode__ === 'ios') {
|
|
437
|
+
opt = {
|
|
438
|
+
headerBackTitleVisible: false
|
|
439
|
+
}
|
|
440
|
+
}
|
|
407
441
|
navigation.setOptions({
|
|
408
|
-
headerShown:
|
|
442
|
+
headerShown: !isCustom,
|
|
443
|
+
headerShadowVisible: false,
|
|
409
444
|
headerTitle: pageConfig.navigationBarTitleText || '',
|
|
410
445
|
headerStyle: {
|
|
411
446
|
backgroundColor: pageConfig.navigationBarBackgroundColor || '#000000'
|
|
412
447
|
},
|
|
413
|
-
|
|
448
|
+
headerTitleAlign: 'center',
|
|
449
|
+
headerTintColor: pageConfig.navigationBarTextStyle || 'white',
|
|
450
|
+
...opt
|
|
414
451
|
})
|
|
415
452
|
}, [])
|
|
416
453
|
|
|
417
454
|
navigation.insets = useSafeAreaInsets()
|
|
418
455
|
|
|
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
|
-
}
|
|
456
|
+
return createElement(GestureHandlerRootView,
|
|
457
|
+
{
|
|
458
|
+
style: {
|
|
459
|
+
flex: 1,
|
|
460
|
+
backgroundColor: pageConfig.backgroundColor || '#ffffff'
|
|
430
461
|
},
|
|
431
|
-
|
|
462
|
+
ref: rootRef
|
|
463
|
+
},
|
|
464
|
+
// todo custom portal host for active route
|
|
465
|
+
createElement(Provider,
|
|
466
|
+
null,
|
|
467
|
+
createElement(RouteContext.Provider,
|
|
432
468
|
{
|
|
433
|
-
value:
|
|
469
|
+
value: currentPageId
|
|
434
470
|
},
|
|
435
471
|
createElement(defaultOptions,
|
|
436
472
|
{
|
|
437
473
|
navigation,
|
|
438
474
|
route,
|
|
439
|
-
|
|
475
|
+
id: currentPageId
|
|
440
476
|
}
|
|
441
477
|
)
|
|
442
478
|
)
|