@mpxjs/core 2.9.50 → 2.9.58
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/package.json +3 -3
- package/src/convertor/wxToAli.js +0 -9
- package/src/platform/builtInMixins/pageStatusMixin.web.js +6 -5
- package/src/platform/builtInMixins/proxyEventMixin.ios.js +9 -9
- package/src/platform/builtInMixins/refsMixin.ios.js +64 -286
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +5 -2
- package/src/platform/createApp.ios.js +57 -3
- package/src/platform/export/api.js +5 -2
- package/src/platform/export/api.web.js +12 -9
- package/src/platform/patch/ali/getDefaultOptions.js +5 -5
- package/src/platform/patch/react/getDefaultOptions.ios.js +156 -18
- package/src/platform/patch/swan/lifecycle.js +4 -2
- package/src/platform/patch/wx/getDefaultOptions.js +2 -2
- package/src/platform/patch/wx/lifecycle.js +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/core",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.58",
|
|
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.58",
|
|
23
23
|
"lodash": "^4.1.1",
|
|
24
24
|
"miniprogram-api-typings": "^3.10.0"
|
|
25
25
|
},
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"url": "https://github.com/didi/mpx/issues"
|
|
82
82
|
},
|
|
83
83
|
"sideEffects": false,
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "49fe4c4bc46ff4bf87cd8adde37981d4b4134aa7"
|
|
85
85
|
}
|
package/src/convertor/wxToAli.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as wxLifecycle from '../platform/patch/wx/lifecycle'
|
|
2
2
|
import * as aliLifecycle from '../platform/patch/ali/lifecycle'
|
|
3
3
|
import { mergeLifecycle } from './mergeLifecycle'
|
|
4
|
-
import { mergeToArray } from '../core/mergeOptions'
|
|
5
4
|
import { error, hasOwn, isDev } from '@mpxjs/utils'
|
|
6
5
|
import { implemented } from '../core/implement'
|
|
7
6
|
|
|
@@ -60,14 +59,6 @@ export default {
|
|
|
60
59
|
options.props = props
|
|
61
60
|
delete options.properties
|
|
62
61
|
}
|
|
63
|
-
if (options.onResize) {
|
|
64
|
-
mergeToArray(options, {
|
|
65
|
-
events: {
|
|
66
|
-
onResize: options.onResize
|
|
67
|
-
}
|
|
68
|
-
}, 'events')
|
|
69
|
-
delete options.onResize
|
|
70
|
-
}
|
|
71
62
|
notSupportTip(options)
|
|
72
63
|
}
|
|
73
64
|
}
|
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
CREATED,
|
|
4
4
|
ONHIDE,
|
|
5
5
|
ONSHOW,
|
|
6
|
-
ONLOAD
|
|
6
|
+
ONLOAD,
|
|
7
|
+
ONRESIZE
|
|
7
8
|
} from '../../core/innerLifecycle'
|
|
8
9
|
import { isFunction, isBrowser } from '@mpxjs/utils'
|
|
9
10
|
|
|
@@ -35,11 +36,11 @@ function onResize () {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
const
|
|
39
|
+
const pageInstance = getCurrentPageInstance()
|
|
39
40
|
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
if (pageInstance) {
|
|
42
|
+
pageInstance.mpxPageStatus = `resize${count++}`
|
|
43
|
+
pageInstance.__mpxProxy.callHook(ONRESIZE, [systemInfo])
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { error } from '@mpxjs/utils'
|
|
1
|
+
import { error, setByPath } from '@mpxjs/utils'
|
|
2
2
|
import Mpx from '../../index'
|
|
3
3
|
|
|
4
4
|
export default function proxyEventMixin () {
|
|
@@ -33,15 +33,15 @@ export default function proxyEventMixin () {
|
|
|
33
33
|
}
|
|
34
34
|
})
|
|
35
35
|
return returnedValue
|
|
36
|
+
},
|
|
37
|
+
__model (expr, $event, valuePath = ['value'], filterMethod) {
|
|
38
|
+
const innerFilter = {
|
|
39
|
+
trim: val => typeof val === 'string' && val.trim()
|
|
40
|
+
}
|
|
41
|
+
const originValue = valuePath.reduce((acc, cur) => acc[cur], $event.detail)
|
|
42
|
+
const value = filterMethod ? (innerFilter[filterMethod] ? innerFilter[filterMethod](originValue) : typeof this[filterMethod] === 'function' ? this[filterMethod](originValue) : originValue) : originValue
|
|
43
|
+
setByPath(this, expr, value)
|
|
36
44
|
}
|
|
37
|
-
// __model (expr, $event, valuePath = ['value'], filterMethod) {
|
|
38
|
-
// const innerFilter = {
|
|
39
|
-
// trim: val => typeof val === 'string' && val.trim()
|
|
40
|
-
// }
|
|
41
|
-
// const originValue = valuePath.reduce((acc, cur) => acc[cur], $event.detail)
|
|
42
|
-
// const value = filterMethod ? (innerFilter[filterMethod] ? innerFilter[filterMethod](originValue) : typeof this[filterMethod] === 'function' ? this[filterMethod](originValue) : originValue) : originValue
|
|
43
|
-
// setByPath(this, expr, value)
|
|
44
|
-
// }
|
|
45
45
|
}
|
|
46
46
|
return {
|
|
47
47
|
methods
|
|
@@ -1,303 +1,59 @@
|
|
|
1
|
-
import { BEFORECREATE } from '../../core/innerLifecycle'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
const _createSelectorQuery = (runCb) => {
|
|
6
|
-
return {
|
|
7
|
-
exec: (cb = noop) => {
|
|
8
|
-
runCb().then(res => {
|
|
9
|
-
cb(res)
|
|
10
|
-
})
|
|
11
|
-
},
|
|
12
|
-
in: () => {
|
|
13
|
-
warn('please use wx:ref to get NodesRef')
|
|
14
|
-
},
|
|
15
|
-
select: () => {
|
|
16
|
-
warn('please use wx:ref to get NodesRef')
|
|
17
|
-
},
|
|
18
|
-
selectAll: () => {
|
|
19
|
-
warn('please use wx:ref to get NodesRef')
|
|
20
|
-
},
|
|
21
|
-
selectViewport: () => { // 有点难实现,dimension 目前没有暴露相关 api
|
|
22
|
-
warn('please use wx:ref')
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const flushRefFns = (nodeInstances, fns) => {
|
|
28
|
-
const mountedNodeInstance = nodeInstances
|
|
29
|
-
.map(instance => instance.getNodeInstance())
|
|
30
|
-
.filter(({ nodeRef }) => nodeRef.current) // 如果有 nodeRef,表明目前组件处于挂载中
|
|
31
|
-
if (mountedNodeInstance.length) {
|
|
32
|
-
return Promise.all(mountedNodeInstance.map(instance => flushFns(instance, fns)))
|
|
33
|
-
} else {
|
|
34
|
-
return Promise.resolve(null)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const flushFns = (nodeInstance, fns) => {
|
|
39
|
-
return Promise.all(fns.map(fn => fn(nodeInstance))).then((res) => {
|
|
40
|
-
return res.reduce((preVal, curVal) => {
|
|
41
|
-
return Object.assign(preVal, curVal)
|
|
42
|
-
}, {})
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const wrapFn = (fn) => {
|
|
47
|
-
return (nodeRef) => {
|
|
48
|
-
return new Promise((resolve) => {
|
|
49
|
-
fn(nodeRef, resolve)
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const getMeasureProps = (measureProps = []) => {
|
|
55
|
-
return wrapFn((nodeInstance, resolve) => {
|
|
56
|
-
const nodeRef = nodeInstance.nodeRef.current
|
|
57
|
-
setTimeout(() => {
|
|
58
|
-
nodeRef.measure(function (x, y, width, height, pageX, pageY) {
|
|
59
|
-
const rectAndSize = {
|
|
60
|
-
width,
|
|
61
|
-
height,
|
|
62
|
-
left: pageX,
|
|
63
|
-
top: pageY,
|
|
64
|
-
right: pageX + width,
|
|
65
|
-
bottom: pageY + height
|
|
66
|
-
}
|
|
67
|
-
const result = measureProps.reduce((preVal, key) => {
|
|
68
|
-
return Object.assign(preVal, { [key]: rectAndSize[key] || 0 })
|
|
69
|
-
}, {})
|
|
70
|
-
resolve(result)
|
|
71
|
-
})
|
|
72
|
-
}, 30) // 延迟,等待组件在rn视图上真正渲染出来
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const getDataset = (props) => {
|
|
77
|
-
return wrapFn((nodeRef, resolve) => {
|
|
78
|
-
props = nodeRef.props.current
|
|
79
|
-
resolve({
|
|
80
|
-
dataset: collectDataset(props)
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const getPlainProps = (config) => {
|
|
86
|
-
return wrapFn((nodeRef, resolve) => {
|
|
87
|
-
const res = {}
|
|
88
|
-
const props = nodeRef.props.current
|
|
89
|
-
config.forEach((key) => {
|
|
90
|
-
// props 属性默认不转驼峰,用户写什么格式不会变化,取值做兼容
|
|
91
|
-
res[key] = props[key] || props[hump2dash(key)] || ''
|
|
92
|
-
})
|
|
93
|
-
resolve(res)
|
|
94
|
-
})
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const getComputedStyle = (config = []) => {
|
|
98
|
-
return wrapFn((nodeRef, resolve) => {
|
|
99
|
-
config = new Set(config)
|
|
100
|
-
const res = {}
|
|
101
|
-
const styles = nodeRef.props.current.style || []
|
|
102
|
-
const defaultStyle = nodeRef.instance.defaultStyle || {}
|
|
103
|
-
const computedStyle = StyleSheet.flatten([defaultStyle, ...styles])
|
|
104
|
-
config.forEach((key) => {
|
|
105
|
-
const humpKey = dash2hump(key)
|
|
106
|
-
// 取 style 的 key 是根据传入的 key 来设置,传什么设置什么 key,只不过取值需要做兼容
|
|
107
|
-
res[key] = computedStyle[key] || computedStyle[humpKey] || ''
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
resolve(res)
|
|
111
|
-
})
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const getInstanceConfig = (config) => {
|
|
115
|
-
return wrapFn((nodeRef, resolve) => {
|
|
116
|
-
const instance = nodeRef.instance
|
|
117
|
-
resolve({ [config]: instance[config] || {} })
|
|
118
|
-
})
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const defaultScrollOffset = {
|
|
122
|
-
scrollLeft: 0,
|
|
123
|
-
scrollTop: 0,
|
|
124
|
-
scrollHeight: 0,
|
|
125
|
-
scrollWidth: 0
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const getScrollOffset = () => {
|
|
129
|
-
return wrapFn((nodeRef, resolve) => {
|
|
130
|
-
const instance = nodeRef.instance
|
|
131
|
-
resolve((instance.scrollOffset && instance.scrollOffset.current) || defaultScrollOffset)
|
|
132
|
-
})
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// const getScrollOffsetFallback = (cb) => {
|
|
136
|
-
// const res = {
|
|
137
|
-
// scrollLeft: 0,
|
|
138
|
-
// scrollTop: 0,
|
|
139
|
-
// scrollHeight: 0,
|
|
140
|
-
// scrollWidth: 0
|
|
141
|
-
// }
|
|
142
|
-
// cb(res)
|
|
143
|
-
// }
|
|
144
|
-
|
|
145
|
-
const RECT = ['left', 'top', 'right', 'bottom']
|
|
146
|
-
const SIZE = ['width', 'height']
|
|
147
|
-
|
|
148
|
-
function _createNodesRef (nodeRefs = []) {
|
|
149
|
-
const fields = (config, cb = noop) => {
|
|
150
|
-
const plainProps = []
|
|
151
|
-
const measureProps = []
|
|
152
|
-
const computedStyle = []
|
|
153
|
-
const fns = []
|
|
154
|
-
|
|
155
|
-
for (const key in config) {
|
|
156
|
-
const value = config[key]
|
|
157
|
-
if (Array.isArray(value) && value.length) {
|
|
158
|
-
if (key === 'properties') {
|
|
159
|
-
// wx 最终输出的 properties 字段都会转化为驼峰,所以在这里提前处理为最终的字段格式
|
|
160
|
-
plainProps.push(...value.map(v => dash2hump(v)))
|
|
161
|
-
} else if (key === 'computedStyle') {
|
|
162
|
-
const _computedStyle = config.computedStyle
|
|
163
|
-
for (let i = _computedStyle.length - 1; i >= 0; i--) {
|
|
164
|
-
const style = _computedStyle[i]
|
|
165
|
-
if (RECT.includes(style) || SIZE.includes(style)) {
|
|
166
|
-
measureProps.push(style)
|
|
167
|
-
_computedStyle.splice(i, 1)
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
if (_computedStyle.length) {
|
|
171
|
-
computedStyle.push(..._computedStyle)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
} else if (isBoolean(value) && value) {
|
|
175
|
-
switch (key) {
|
|
176
|
-
case 'rect':
|
|
177
|
-
measureProps.push(...RECT)
|
|
178
|
-
break
|
|
179
|
-
case 'size':
|
|
180
|
-
measureProps.push(...SIZE)
|
|
181
|
-
break
|
|
182
|
-
case 'scrollOffset':
|
|
183
|
-
fns.push(getScrollOffset())
|
|
184
|
-
break
|
|
185
|
-
case 'dataset':
|
|
186
|
-
fns.push(getDataset())
|
|
187
|
-
break
|
|
188
|
-
case 'node':
|
|
189
|
-
case 'context':
|
|
190
|
-
case 'ref':
|
|
191
|
-
fns.push(getInstanceConfig(key))
|
|
192
|
-
break
|
|
193
|
-
default:
|
|
194
|
-
plainProps.push(key)
|
|
195
|
-
break
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (plainProps.length) {
|
|
201
|
-
fns.push(getPlainProps(plainProps))
|
|
202
|
-
}
|
|
203
|
-
if (measureProps.length) {
|
|
204
|
-
const nodeInstance = nodeRefs[0] && nodeRefs[0].getNodeInstance()
|
|
205
|
-
const hasMeasureFn = nodeInstance && nodeInstance.nodeRef.current && nodeInstance.nodeRef.current.measure
|
|
206
|
-
if (hasMeasureFn) {
|
|
207
|
-
fns.push(getMeasureProps(measureProps))
|
|
208
|
-
} else {
|
|
209
|
-
computedStyle.push(...measureProps)
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
if (computedStyle.length) {
|
|
213
|
-
fns.push(getComputedStyle(computedStyle))
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const runCb = () => {
|
|
217
|
-
return flushRefFns(nodeRefs, fns).then((result) => {
|
|
218
|
-
// wx的数据格式:对于具体方法接受到的回调传参,如果获取的 nodeRef 只有一个,那么只需要返回一条数据而不是数组,但是 exec 里面统一都是数组
|
|
219
|
-
cb(result && result.length === 1 ? result[0] : result)
|
|
220
|
-
return result
|
|
221
|
-
})
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return _createSelectorQuery(runCb)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const boundingClientRect = (cb = noop) => {
|
|
228
|
-
const config = {
|
|
229
|
-
id: true,
|
|
230
|
-
dataset: true,
|
|
231
|
-
rect: true,
|
|
232
|
-
size: true
|
|
233
|
-
}
|
|
234
|
-
return fields(config, cb)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const context = (cb = noop) => {
|
|
238
|
-
const config = {
|
|
239
|
-
context: true
|
|
240
|
-
}
|
|
241
|
-
return fields(config, cb)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const node = (cb = noop) => {
|
|
245
|
-
const config = {
|
|
246
|
-
node: true
|
|
247
|
-
}
|
|
248
|
-
return fields(config, cb)
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const ref = (cb = noop) => {
|
|
252
|
-
const config = {
|
|
253
|
-
ref: true
|
|
254
|
-
}
|
|
255
|
-
return fields(config, cb)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const scrollOffset = (cb = noop) => {
|
|
259
|
-
const config = {
|
|
260
|
-
id: true,
|
|
261
|
-
dataset: true,
|
|
262
|
-
scrollOffset: true
|
|
263
|
-
}
|
|
264
|
-
return fields(config, cb)
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return {
|
|
268
|
-
fields,
|
|
269
|
-
boundingClientRect,
|
|
270
|
-
context,
|
|
271
|
-
node,
|
|
272
|
-
ref,
|
|
273
|
-
scrollOffset
|
|
274
|
-
}
|
|
275
|
-
}
|
|
1
|
+
import { BEFORECREATE, CREATED } from '../../core/innerLifecycle'
|
|
2
|
+
import { createSelectorQuery } from '@mpxjs/api-proxy'
|
|
3
|
+
import { computed } from '../../observer/computed'
|
|
276
4
|
|
|
277
5
|
export default function getRefsMixin () {
|
|
278
6
|
return {
|
|
279
7
|
[BEFORECREATE] () {
|
|
280
8
|
this.__refs = {}
|
|
281
9
|
this.$refs = {}
|
|
10
|
+
},
|
|
11
|
+
// __getRefs强依赖数据响应,需要在CREATED中执行
|
|
12
|
+
[CREATED] () {
|
|
282
13
|
this.__getRefs()
|
|
283
14
|
},
|
|
284
15
|
methods: {
|
|
285
16
|
__getRefs () {
|
|
286
17
|
const refs = this.__getRefsData() || []
|
|
287
18
|
const target = this
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
19
|
+
this.__selectorMap = computed(() => {
|
|
20
|
+
const selectorMap = {}
|
|
21
|
+
refs.forEach(({ key, type, sKeys }) => {
|
|
22
|
+
// sKeys 是使用 wx:ref 没有值的标记场景,支持运行时的 createSelectorQuery 的使用
|
|
23
|
+
if (sKeys) {
|
|
24
|
+
sKeys.forEach((item = {}) => {
|
|
25
|
+
const computedKey = item.key
|
|
26
|
+
const prefix = item.prefix
|
|
27
|
+
const selectors = this[computedKey] || ''
|
|
28
|
+
selectors.trim().split(/\s+/).forEach(item => {
|
|
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 })
|
|
299
37
|
}
|
|
300
38
|
})
|
|
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
|
+
}
|
|
301
57
|
})
|
|
302
58
|
},
|
|
303
59
|
__getRefVal (key) {
|
|
@@ -305,6 +61,28 @@ export default function getRefsMixin () {
|
|
|
305
61
|
this.__refs[key] = []
|
|
306
62
|
}
|
|
307
63
|
return (instance) => instance && this.__refs[key].push(instance)
|
|
64
|
+
},
|
|
65
|
+
__selectRef (selector, refType, all = false) {
|
|
66
|
+
const splitedSelector = selector.match(/(#|\.)?\w+/g) || []
|
|
67
|
+
const refsArr = splitedSelector.map(selector => {
|
|
68
|
+
const selectorMap = this.__selectorMap?.value[selector] || []
|
|
69
|
+
const res = []
|
|
70
|
+
selectorMap.forEach(({ type, key }) => {
|
|
71
|
+
if (type === refType) {
|
|
72
|
+
const _refs = this.__refs[key] || []
|
|
73
|
+
res.push(..._refs)
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
return res
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const refs = refsArr.reduce((preRefs, curRefs, curIndex) => {
|
|
80
|
+
if (curIndex === 0) return curRefs
|
|
81
|
+
curRefs = new Set(curRefs)
|
|
82
|
+
return preRefs.filter(p => curRefs.has(p))
|
|
83
|
+
}, [])
|
|
84
|
+
|
|
85
|
+
return all ? refs : refs[0]
|
|
308
86
|
}
|
|
309
87
|
}
|
|
310
88
|
}
|
|
@@ -41,8 +41,8 @@ function stringifyDynamicClass (value) {
|
|
|
41
41
|
|
|
42
42
|
const listDelimiter = /;(?![^(]*[)])/g
|
|
43
43
|
const propertyDelimiter = /:(.+)/
|
|
44
|
-
const rpxRegExp = /^\s*(
|
|
45
|
-
const pxRegExp = /^\s*(
|
|
44
|
+
const rpxRegExp = /^\s*(-?\d+(\.\d+)?)rpx\s*$/
|
|
45
|
+
const pxRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/
|
|
46
46
|
|
|
47
47
|
function parseStyleText (cssText) {
|
|
48
48
|
const res = {}
|
|
@@ -106,6 +106,9 @@ export default function styleHelperMixin (type) {
|
|
|
106
106
|
// px = rpx * (750 / 屏幕宽度)
|
|
107
107
|
return value * width / 750
|
|
108
108
|
},
|
|
109
|
+
__getClass (staticClass, dynamicClass) {
|
|
110
|
+
return concat(staticClass, stringifyDynamicClass(dynamicClass))
|
|
111
|
+
},
|
|
109
112
|
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, show) {
|
|
110
113
|
const result = []
|
|
111
114
|
const classMap = {}
|
|
@@ -5,9 +5,15 @@ import { mergeLifecycle } from '../convertor/mergeLifecycle'
|
|
|
5
5
|
import * as wxLifecycle from '../platform/patch/wx/lifecycle'
|
|
6
6
|
import Mpx from '../index'
|
|
7
7
|
import { createElement, memo, useRef, useEffect } from 'react'
|
|
8
|
+
import * as ReactNative from 'react-native'
|
|
9
|
+
import { ref } from '../observer/ref'
|
|
8
10
|
|
|
9
11
|
const appHooksMap = makeMap(mergeLifecycle(wxLifecycle.LIFECYCLE).app)
|
|
10
12
|
|
|
13
|
+
function getOrientation (window = ReactNative.Dimensions.get('window')) {
|
|
14
|
+
return window.width > window.height ? 'landscape' : 'portrait'
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
function filterOptions (options, appData) {
|
|
12
18
|
const newOptions = {}
|
|
13
19
|
Object.keys(options).forEach(key => {
|
|
@@ -39,6 +45,10 @@ export default function createApp (option, config = {}) {
|
|
|
39
45
|
const { rawOptions, currentInject } = transferOptions(option, 'app', false)
|
|
40
46
|
const defaultOptions = filterOptions(spreadProp(rawOptions, 'methods'), appData)
|
|
41
47
|
defaultOptions.onAppInit && defaultOptions.onAppInit()
|
|
48
|
+
// 在页面script执行前填充getApp()
|
|
49
|
+
global.getApp = function () {
|
|
50
|
+
return appData
|
|
51
|
+
}
|
|
42
52
|
const pages = currentInject.getPages() || {}
|
|
43
53
|
const firstPage = currentInject.firstPage
|
|
44
54
|
const Stack = createNativeStackNavigator()
|
|
@@ -64,6 +74,14 @@ export default function createApp (option, config = {}) {
|
|
|
64
74
|
global.__navigationHelper.lastFailCallback = null
|
|
65
75
|
}
|
|
66
76
|
}
|
|
77
|
+
|
|
78
|
+
global.__mpxAppCbs = global.__mpxAppCbs || {
|
|
79
|
+
show: [],
|
|
80
|
+
hide: [],
|
|
81
|
+
error: []
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
global.__mpxAppFocusedState = ref('show')
|
|
67
85
|
global.__mpxOptionsMap[currentInject.moduleId] = memo(() => {
|
|
68
86
|
const instanceRef = useRef(null)
|
|
69
87
|
if (!instanceRef.current) {
|
|
@@ -81,7 +99,45 @@ export default function createApp (option, config = {}) {
|
|
|
81
99
|
}
|
|
82
100
|
global.__mpxEnterOptions = options
|
|
83
101
|
defaultOptions.onLaunch && defaultOptions.onLaunch.call(instance, options)
|
|
102
|
+
if (defaultOptions.onShow) {
|
|
103
|
+
defaultOptions.onShow.call(instance, options)
|
|
104
|
+
global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(instance))
|
|
105
|
+
}
|
|
106
|
+
if (defaultOptions.onHide) {
|
|
107
|
+
global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(instance))
|
|
108
|
+
}
|
|
109
|
+
if (defaultOptions.onError) {
|
|
110
|
+
global.__mpxAppCbs.error.push(defaultOptions.onError.bind(instance))
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => {
|
|
114
|
+
if (currentState === 'active') {
|
|
115
|
+
global.__mpxAppCbs.show.forEach((cb) => {
|
|
116
|
+
cb(options)
|
|
117
|
+
global.__mpxAppFocusedState.value = 'show'
|
|
118
|
+
})
|
|
119
|
+
} else if (currentState === 'background') {
|
|
120
|
+
global.__mpxAppCbs.hide.forEach((cb) => {
|
|
121
|
+
cb()
|
|
122
|
+
global.__mpxAppFocusedState.value = 'hide'
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
let count = 0
|
|
128
|
+
let lastOrientation = getOrientation()
|
|
129
|
+
const resizeSubScription = ReactNative.Dimensions.addEventListener('change', ({ window }) => {
|
|
130
|
+
const orientation = getOrientation(window)
|
|
131
|
+
if (orientation === lastOrientation) return
|
|
132
|
+
lastOrientation = orientation
|
|
133
|
+
global.__mpxAppFocusedState.value = `resize${count++}`
|
|
134
|
+
})
|
|
135
|
+
return () => {
|
|
136
|
+
changeSubscription()
|
|
137
|
+
resizeSubScription && resizeSubScription.remove()
|
|
138
|
+
}
|
|
84
139
|
}, [])
|
|
140
|
+
|
|
85
141
|
return createElement(NavigationContainer,
|
|
86
142
|
{
|
|
87
143
|
ref: navigationRef,
|
|
@@ -96,9 +152,7 @@ export default function createApp (option, config = {}) {
|
|
|
96
152
|
)
|
|
97
153
|
)
|
|
98
154
|
})
|
|
99
|
-
|
|
100
|
-
return appData
|
|
101
|
-
}
|
|
155
|
+
|
|
102
156
|
global.getCurrentPages = function () {
|
|
103
157
|
const navigation = Object.values(global.__mpxPagesMap || {})[0]?.[1]
|
|
104
158
|
if (navigation) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { set, del, reactive } from '../../observer/reactive'
|
|
1
|
+
import { set, del, reactive, isReactive } from '../../observer/reactive'
|
|
2
|
+
import { isRef } from '../../observer/ref'
|
|
2
3
|
import { watch } from '../../observer/watch'
|
|
3
4
|
import { injectMixins } from '../../core/injectMixins'
|
|
4
5
|
|
|
@@ -8,7 +9,9 @@ const APIs = {
|
|
|
8
9
|
observable: reactive,
|
|
9
10
|
watch,
|
|
10
11
|
set,
|
|
11
|
-
delete: del
|
|
12
|
+
delete: del,
|
|
13
|
+
isReactive,
|
|
14
|
+
isRef
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
const InstanceAPIs = {
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
watch,
|
|
3
|
+
reactive,
|
|
4
|
+
isReactive,
|
|
5
|
+
set,
|
|
6
|
+
del,
|
|
7
|
+
isRef
|
|
8
|
+
} from 'vue'
|
|
2
9
|
import { injectMixins } from '../../core/injectMixins'
|
|
3
10
|
|
|
4
|
-
const vm = new Vue()
|
|
5
|
-
const observable = Vue.observable.bind(Vue)
|
|
6
|
-
const watch = vm.$watch.bind(vm)
|
|
7
|
-
const set = Vue.set.bind(Vue)
|
|
8
|
-
const del = Vue.delete.bind(Vue)
|
|
9
|
-
|
|
10
11
|
const APIs = {
|
|
11
12
|
injectMixins,
|
|
12
13
|
mixin: injectMixins,
|
|
13
|
-
observable,
|
|
14
|
+
observable: reactive,
|
|
14
15
|
watch,
|
|
15
16
|
set,
|
|
16
|
-
delete: del
|
|
17
|
+
delete: del,
|
|
18
|
+
isReactive,
|
|
19
|
+
isRef
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
const InstanceAPIs = {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import MpxProxy from '../../../core/proxy'
|
|
2
2
|
import builtInKeysMap from '../builtInKeysMap'
|
|
3
3
|
import mergeOptions from '../../../core/mergeOptions'
|
|
4
|
-
import {
|
|
4
|
+
import { error, diffAndCloneA, hasOwn, noop } from '@mpxjs/utils'
|
|
5
5
|
|
|
6
6
|
function transformApiForProxy (context, currentInject) {
|
|
7
7
|
const rawSetData = context.setData.bind(context)
|
|
@@ -23,7 +23,7 @@ function transformApiForProxy (context, currentInject) {
|
|
|
23
23
|
const validProps = Object.assign({}, options.properties, options.props)
|
|
24
24
|
if (context.props) {
|
|
25
25
|
Object.keys(context.props).forEach((key) => {
|
|
26
|
-
if (hasOwn(validProps, key)
|
|
26
|
+
if (hasOwn(validProps, key)) {
|
|
27
27
|
props[key] = context.props[key]
|
|
28
28
|
}
|
|
29
29
|
})
|
|
@@ -129,7 +129,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
129
129
|
if (rawOptions.__nativeRender__ && this.props) {
|
|
130
130
|
const validProps = Object.assign({}, rawOptions.props, rawOptions.properties)
|
|
131
131
|
Object.keys(this.props).forEach((key) => {
|
|
132
|
-
if (hasOwn(validProps, key)
|
|
132
|
+
if (hasOwn(validProps, key)) {
|
|
133
133
|
this.data[key] = this.props[key]
|
|
134
134
|
}
|
|
135
135
|
})
|
|
@@ -143,7 +143,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
143
143
|
const newData = {}
|
|
144
144
|
// 微信原生转换支付宝时,每次props更新将其设置进data模拟微信表现
|
|
145
145
|
Object.keys(nextProps).forEach((key) => {
|
|
146
|
-
if (hasOwn(validProps, key)
|
|
146
|
+
if (hasOwn(validProps, key)) {
|
|
147
147
|
const { diff, clone } = diffAndCloneA(nextProps[key], this.props[key])
|
|
148
148
|
if (diff) newData[key] = clone
|
|
149
149
|
}
|
|
@@ -153,7 +153,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
153
153
|
// 由于支付宝中props透传父级setData的值,此处发生变化的属性实例一定不同,只需浅比较即可确定发生变化的属性
|
|
154
154
|
// 支付宝appx2.0版本后props传递发生变化,此处获取到的nextProps和this.props以及父组件setData的数据引用都不一致,进行了两次深克隆,此处this.props和nextProps的比对需要用deep diff
|
|
155
155
|
Object.keys(nextProps).forEach(key => {
|
|
156
|
-
if (hasOwn(validProps, key)
|
|
156
|
+
if (hasOwn(validProps, key)) {
|
|
157
157
|
const { diff, clone } = diffAndCloneA(nextProps[key], this.props[key])
|
|
158
158
|
// 由于支付宝中透传父级setData的值,此处进行深clone后赋值避免父级存储的miniRenderData部分数据在此处被响应化,在子组件对props赋值时触发父组件的render
|
|
159
159
|
if (diff) this[key] = clone
|
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, createElement, memo, forwardRef, useImperativeHandle } from 'react'
|
|
1
|
+
import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, createElement, memo, forwardRef, useImperativeHandle, useContext, createContext, Fragment } from 'react'
|
|
2
2
|
import * as ReactNative from 'react-native'
|
|
3
3
|
import { ReactiveEffect } from '../../../observer/effect'
|
|
4
|
+
import { watch } from '../../../observer/watch'
|
|
5
|
+
import { reactive, set } from '../../../observer/reactive'
|
|
4
6
|
import { hasOwn, isFunction, noop, isObject, error, getByPath, collectDataset } from '@mpxjs/utils'
|
|
5
7
|
import MpxProxy from '../../../core/proxy'
|
|
6
|
-
import { BEFOREUPDATE, UPDATED,
|
|
8
|
+
import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE } from '../../../core/innerLifecycle'
|
|
7
9
|
import mergeOptions from '../../../core/mergeOptions'
|
|
8
10
|
import { queueJob } from '../../../observer/scheduler'
|
|
11
|
+
import { createSelectorQuery } from '@mpxjs/api-proxy'
|
|
12
|
+
|
|
13
|
+
function getSystemInfo () {
|
|
14
|
+
const window = ReactNative.Dimensions.get('window')
|
|
15
|
+
const screen = ReactNative.Dimensions.get('screen')
|
|
16
|
+
return {
|
|
17
|
+
deviceOrientation: window.width > window.height ? 'landscape' : 'portrait',
|
|
18
|
+
size: {
|
|
19
|
+
screenWidth: screen.width,
|
|
20
|
+
screenHeight: screen.height,
|
|
21
|
+
windowWidth: window.width,
|
|
22
|
+
windowHeight: window.height
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
9
26
|
|
|
10
27
|
function getRootProps (props) {
|
|
11
28
|
const rootProps = {}
|
|
@@ -36,6 +53,7 @@ function createEffect (proxy, components, props) {
|
|
|
36
53
|
}
|
|
37
54
|
update.id = proxy.uid
|
|
38
55
|
const getComponent = (tagName) => {
|
|
56
|
+
if (tagName === 'block') return Fragment
|
|
39
57
|
return components[tagName] || getByPath(ReactNative, tagName)
|
|
40
58
|
}
|
|
41
59
|
proxy.effect = new ReactiveEffect(() => {
|
|
@@ -51,13 +69,20 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
51
69
|
__getProps () {
|
|
52
70
|
const propsData = {}
|
|
53
71
|
const props = propsRef.current
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
Object.keys(validProps).forEach((key) => {
|
|
73
|
+
if (hasOwn(props, key)) {
|
|
74
|
+
propsData[key] = props[key]
|
|
75
|
+
} else {
|
|
76
|
+
let field = validProps[key]
|
|
77
|
+
if (isFunction(field) || field === null) {
|
|
78
|
+
field = {
|
|
79
|
+
type: field
|
|
80
|
+
}
|
|
58
81
|
}
|
|
59
|
-
|
|
60
|
-
|
|
82
|
+
// 处理props默认值
|
|
83
|
+
propsData[key] = field.value
|
|
84
|
+
}
|
|
85
|
+
})
|
|
61
86
|
return propsData
|
|
62
87
|
},
|
|
63
88
|
__getSlot (name) {
|
|
@@ -111,8 +136,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
111
136
|
},
|
|
112
137
|
triggerEvent (eventName, eventDetail) {
|
|
113
138
|
const props = propsRef.current
|
|
114
|
-
const
|
|
115
|
-
const handler = props && (props['bind' + handlerName] || props['catch' + handlerName] || props['capture-bind' + handlerName] || props['capture-catch' + handlerName])
|
|
139
|
+
const handler = props && (props['bind' + eventName] || props['catch' + eventName] || props['capture-bind' + eventName] || props['capture-catch' + eventName])
|
|
116
140
|
if (handler && typeof handler === 'function') {
|
|
117
141
|
const timeStamp = +new Date()
|
|
118
142
|
const dataset = collectDataset(props)
|
|
@@ -134,14 +158,14 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
134
158
|
handler.call(this, eventObj)
|
|
135
159
|
}
|
|
136
160
|
},
|
|
137
|
-
selectComponent () {
|
|
138
|
-
|
|
161
|
+
selectComponent (selector) {
|
|
162
|
+
return this.__selectRef(selector, 'component')
|
|
139
163
|
},
|
|
140
|
-
selectAllComponents () {
|
|
141
|
-
|
|
164
|
+
selectAllComponents (selector) {
|
|
165
|
+
return this.__selectRef(selector, 'component', true)
|
|
142
166
|
},
|
|
143
167
|
createSelectorQuery () {
|
|
144
|
-
|
|
168
|
+
return createSelectorQuery().in(this)
|
|
145
169
|
},
|
|
146
170
|
createIntersectionObserver () {
|
|
147
171
|
error('createIntersectionObserver is not supported in react native, please use ref instead')
|
|
@@ -175,7 +199,7 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
175
199
|
proxy.created()
|
|
176
200
|
|
|
177
201
|
if (type === 'page') {
|
|
178
|
-
proxy.callHook(ONLOAD, [props.route.params])
|
|
202
|
+
proxy.callHook(ONLOAD, [props.route.params || {}])
|
|
179
203
|
}
|
|
180
204
|
|
|
181
205
|
Object.assign(proxy, {
|
|
@@ -207,6 +231,105 @@ function createInstance ({ propsRef, type, rawOptions, currentInject, validProps
|
|
|
207
231
|
return instance
|
|
208
232
|
}
|
|
209
233
|
|
|
234
|
+
function hasPageHook (mpxProxy, hookNames) {
|
|
235
|
+
const options = mpxProxy.options
|
|
236
|
+
const type = options.__type__
|
|
237
|
+
return hookNames.some(h => {
|
|
238
|
+
if (mpxProxy.hasHook(h)) {
|
|
239
|
+
return true
|
|
240
|
+
}
|
|
241
|
+
if (type === 'page') {
|
|
242
|
+
return isFunction(options.methods && options.methods[h])
|
|
243
|
+
} else if (type === 'component') {
|
|
244
|
+
return options.pageLifetimes && isFunction(options.pageLifetimes[h])
|
|
245
|
+
}
|
|
246
|
+
return false
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const routeContext = createContext(null)
|
|
251
|
+
|
|
252
|
+
const triggerPageStatusHook = (mpxProxy, event) => {
|
|
253
|
+
mpxProxy.callHook(event === 'show' ? ONSHOW : ONHIDE)
|
|
254
|
+
const pageLifetimes = mpxProxy.options.pageLifetimes
|
|
255
|
+
if (pageLifetimes) {
|
|
256
|
+
const instance = mpxProxy.target
|
|
257
|
+
isFunction(pageLifetimes[event]) && pageLifetimes[event].call(instance)
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const triggerResizeEvent = (mpxProxy) => {
|
|
262
|
+
const type = mpxProxy.options.__type__
|
|
263
|
+
const systemInfo = getSystemInfo()
|
|
264
|
+
const target = mpxProxy.target
|
|
265
|
+
mpxProxy.callHook(ONRESIZE, [systemInfo])
|
|
266
|
+
if (type === 'page') {
|
|
267
|
+
target.onResize && target.onResize(systemInfo)
|
|
268
|
+
} else {
|
|
269
|
+
const pageLifetimes = mpxProxy.options.pageLifetimes
|
|
270
|
+
pageLifetimes && isFunction(pageLifetimes.resize) && pageLifetimes.resize.call(target, systemInfo)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function usePageContext (mpxProxy) {
|
|
275
|
+
const { routeName } = useContext(routeContext) || {}
|
|
276
|
+
|
|
277
|
+
useEffect(() => {
|
|
278
|
+
let unWatch
|
|
279
|
+
const hasShowHook = hasPageHook(mpxProxy, [ONSHOW, 'show'])
|
|
280
|
+
const hasHideHook = hasPageHook(mpxProxy, [ONHIDE, 'hide'])
|
|
281
|
+
const hasResizeHook = hasPageHook(mpxProxy, [ONRESIZE, 'resize'])
|
|
282
|
+
if (hasShowHook || hasHideHook || hasResizeHook) {
|
|
283
|
+
if (hasOwn(pageStatusContext, routeName)) {
|
|
284
|
+
unWatch = watch(() => pageStatusContext[routeName], (newVal) => {
|
|
285
|
+
if (newVal === 'show' || newVal === 'hide') {
|
|
286
|
+
triggerPageStatusHook(mpxProxy, newVal)
|
|
287
|
+
} else if (/^resize/.test(newVal)) {
|
|
288
|
+
triggerResizeEvent(mpxProxy)
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return () => {
|
|
295
|
+
unWatch && unWatch()
|
|
296
|
+
}
|
|
297
|
+
}, [])
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const pageStatusContext = reactive({})
|
|
301
|
+
function setPageStatus (routeName, val) {
|
|
302
|
+
set(pageStatusContext, routeName, val)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function usePageStatus (navigation, route) {
|
|
306
|
+
let isFocused = true
|
|
307
|
+
setPageStatus(route.name, '')
|
|
308
|
+
useEffect(() => {
|
|
309
|
+
setPageStatus(route.name, 'show')
|
|
310
|
+
const focusSubscription = navigation.addListener('focus', () => {
|
|
311
|
+
setPageStatus(route.name, 'show')
|
|
312
|
+
isFocused = true
|
|
313
|
+
})
|
|
314
|
+
const blurSubscription = navigation.addListener('blur', () => {
|
|
315
|
+
setPageStatus(route.name, 'hide')
|
|
316
|
+
isFocused = false
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => {
|
|
320
|
+
if (isFocused) {
|
|
321
|
+
setPageStatus(route.name, value)
|
|
322
|
+
}
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
return () => {
|
|
326
|
+
focusSubscription()
|
|
327
|
+
blurSubscription()
|
|
328
|
+
unWatchAppFocusedState()
|
|
329
|
+
}
|
|
330
|
+
}, [navigation])
|
|
331
|
+
}
|
|
332
|
+
|
|
210
333
|
export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
211
334
|
rawOptions = mergeOptions(rawOptions, type, false)
|
|
212
335
|
const components = Object.assign({}, rawOptions.components, currentInject.getComponents())
|
|
@@ -232,13 +355,15 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
232
355
|
// 处理props更新
|
|
233
356
|
propsRef.current = props
|
|
234
357
|
Object.keys(props).forEach(key => {
|
|
235
|
-
if (hasOwn(validProps, key)
|
|
358
|
+
if (hasOwn(validProps, key)) {
|
|
236
359
|
instance[key] = props[key]
|
|
237
360
|
}
|
|
238
361
|
})
|
|
239
362
|
proxy.propsUpdated()
|
|
240
363
|
}
|
|
241
364
|
|
|
365
|
+
usePageContext(proxy)
|
|
366
|
+
|
|
242
367
|
useEffect(() => {
|
|
243
368
|
if (proxy.pendingUpdatedFlag) {
|
|
244
369
|
proxy.pendingUpdatedFlag = false
|
|
@@ -265,6 +390,8 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
265
390
|
const { Provider } = global.__navigationHelper
|
|
266
391
|
const pageConfig = Object.assign({}, global.__mpxPageConfig, currentInject.pageConfig)
|
|
267
392
|
const Page = ({ navigation, route }) => {
|
|
393
|
+
usePageStatus(navigation, route)
|
|
394
|
+
|
|
268
395
|
useLayoutEffect(() => {
|
|
269
396
|
navigation.setOptions({
|
|
270
397
|
headerTitle: pageConfig.navigationBarTitleText || '',
|
|
@@ -284,7 +411,18 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
284
411
|
backgroundColor: pageConfig.backgroundColor || '#ffffff'
|
|
285
412
|
}
|
|
286
413
|
},
|
|
287
|
-
createElement(
|
|
414
|
+
createElement(routeContext.Provider,
|
|
415
|
+
{
|
|
416
|
+
value: { routeName: route.name }
|
|
417
|
+
},
|
|
418
|
+
createElement(defaultOptions,
|
|
419
|
+
{
|
|
420
|
+
navigation,
|
|
421
|
+
route,
|
|
422
|
+
pageConfig
|
|
423
|
+
}
|
|
424
|
+
)
|
|
425
|
+
)
|
|
288
426
|
)
|
|
289
427
|
)
|
|
290
428
|
}
|
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
MOUNTED,
|
|
5
5
|
ONSHOW,
|
|
6
6
|
ONHIDE,
|
|
7
|
-
ONLOAD
|
|
7
|
+
ONLOAD,
|
|
8
|
+
ONRESIZE
|
|
8
9
|
} from '../../../core/innerLifecycle'
|
|
9
10
|
|
|
10
11
|
const APP_HOOKS = [
|
|
@@ -47,7 +48,8 @@ export const lifecycleProxyMap = {
|
|
|
47
48
|
[UNMOUNTED]: ['detached', 'onUnload'],
|
|
48
49
|
[ONSHOW]: ['pageShow', 'onShow'],
|
|
49
50
|
[ONHIDE]: ['pageHide', 'onHide'],
|
|
50
|
-
[ONLOAD]: ['onLoad']
|
|
51
|
+
[ONLOAD]: ['onLoad'],
|
|
52
|
+
[ONRESIZE]: ['onResize']
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
export const LIFECYCLE = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasOwn, noop } from '@mpxjs/utils'
|
|
1
|
+
import { hasOwn, noop, isFunction } from '@mpxjs/utils'
|
|
2
2
|
import MpxProxy from '../../../core/proxy'
|
|
3
3
|
import builtInKeysMap from '../builtInKeysMap'
|
|
4
4
|
import mergeOptions from '../../../core/mergeOptions'
|
|
@@ -16,7 +16,7 @@ function transformProperties (properties) {
|
|
|
16
16
|
type: null
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
if (
|
|
19
|
+
if (isFunction(rawFiled)) {
|
|
20
20
|
newFiled = {
|
|
21
21
|
type: rawFiled
|
|
22
22
|
}
|
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
MOUNTED,
|
|
5
5
|
ONSHOW,
|
|
6
6
|
ONHIDE,
|
|
7
|
-
ONLOAD
|
|
7
|
+
ONLOAD,
|
|
8
|
+
ONRESIZE
|
|
8
9
|
} from '../../../core/innerLifecycle'
|
|
9
10
|
|
|
10
11
|
const APP_HOOKS = [
|
|
@@ -52,7 +53,8 @@ export const lifecycleProxyMap = {
|
|
|
52
53
|
[UNMOUNTED]: ['detached', 'onUnload'],
|
|
53
54
|
[ONSHOW]: ['pageShow', 'onShow'],
|
|
54
55
|
[ONHIDE]: ['pageHide', 'onHide'],
|
|
55
|
-
[ONLOAD]: ['onLoad']
|
|
56
|
+
[ONLOAD]: ['onLoad'],
|
|
57
|
+
[ONRESIZE]: ['onResize']
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
export const LIFECYCLE = {
|