@mpxjs/core 2.9.70 → 2.9.71
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 +2 -2
- package/src/core/mergeOptions.js +3 -6
- package/src/core/proxy.js +11 -9
- package/src/platform/builtInMixins/proxyEventMixin.web.js +53 -5
- package/src/platform/createApp.ios.js +35 -36
- package/src/platform/createApp.js +24 -26
- package/src/platform/env/event.js +44 -47
- package/src/platform/env/vuePlugin.js +9 -3
- package/src/platform/export/inject.js +2 -3
- package/src/platform/patch/getDefaultOptions.ios.js +9 -6
- package/src/platform/patch/getDefaultOptions.js +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/core",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.71",
|
|
4
4
|
"description": "mpx runtime core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"miniprogram",
|
|
@@ -109,5 +109,5 @@
|
|
|
109
109
|
"url": "https://github.com/didi/mpx/issues"
|
|
110
110
|
},
|
|
111
111
|
"sideEffects": false,
|
|
112
|
-
"gitHead": "
|
|
112
|
+
"gitHead": "38446f301a17e78dbe3ca7dacd771c79eb7a8ede"
|
|
113
113
|
}
|
package/src/core/mergeOptions.js
CHANGED
|
@@ -122,9 +122,10 @@ function extractObservers (options) {
|
|
|
122
122
|
Object.keys(props).forEach(key => {
|
|
123
123
|
const prop = props[key]
|
|
124
124
|
if (prop && prop.observer) {
|
|
125
|
+
let callback = prop.observer
|
|
126
|
+
delete prop.observer
|
|
125
127
|
mergeWatch(key, {
|
|
126
128
|
handler (...rest) {
|
|
127
|
-
let callback = prop.observer
|
|
128
129
|
if (typeof callback === 'string') {
|
|
129
130
|
callback = this[callback]
|
|
130
131
|
}
|
|
@@ -168,11 +169,7 @@ function extractObservers (options) {
|
|
|
168
169
|
cb = this[cb]
|
|
169
170
|
}
|
|
170
171
|
if (typeof cb === 'function') {
|
|
171
|
-
|
|
172
|
-
val = [val]
|
|
173
|
-
old = [old]
|
|
174
|
-
}
|
|
175
|
-
cb.call(this, ...val, ...old)
|
|
172
|
+
Array.isArray(val) ? cb.call(this, ...val) : cb.call(this, val)
|
|
176
173
|
}
|
|
177
174
|
},
|
|
178
175
|
deep,
|
package/src/core/proxy.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { reactive } from '../observer/reactive'
|
|
1
|
+
import { reactive, defineReactive } from '../observer/reactive'
|
|
2
2
|
import { ReactiveEffect, pauseTracking, resetTracking } from '../observer/effect'
|
|
3
3
|
import { effectScope } from '../platform/export/index'
|
|
4
4
|
import { watch } from '../observer/watch'
|
|
@@ -111,7 +111,7 @@ export default class MpxProxy {
|
|
|
111
111
|
this.uid = uid++
|
|
112
112
|
this.name = options.name || ''
|
|
113
113
|
this.options = options
|
|
114
|
-
this.
|
|
114
|
+
this.shallowReactivePattern = this.options.options?.shallowReactivePattern
|
|
115
115
|
// beforeCreate -> created -> mounted -> unmounted
|
|
116
116
|
this.state = BEFORECREATE
|
|
117
117
|
this.ignoreProxyMap = makeMap(Mpx.config.ignoreProxyWhiteList)
|
|
@@ -145,10 +145,12 @@ export default class MpxProxy {
|
|
|
145
145
|
this.initApi()
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
|
|
149
|
-
if (this.
|
|
148
|
+
processShallowReactive (obj) {
|
|
149
|
+
if (this.shallowReactivePattern && isObject(obj)) {
|
|
150
150
|
Object.keys(obj).forEach((key) => {
|
|
151
|
-
if (this.
|
|
151
|
+
if (this.shallowReactivePattern.test(key)) {
|
|
152
|
+
// 命中shallowReactivePattern的属性将其设置为 shallowReactive
|
|
153
|
+
defineReactive(obj, key, obj[key], true)
|
|
152
154
|
Object.defineProperty(obj, key, {
|
|
153
155
|
enumerable: true,
|
|
154
156
|
// set configurable to false to skip defineReactive
|
|
@@ -290,10 +292,10 @@ export default class MpxProxy {
|
|
|
290
292
|
if (isReact) {
|
|
291
293
|
// react模式下props内部对象透传无需深clone,依赖对象深层的数据响应触发子组件更新
|
|
292
294
|
this.props = this.target.__getProps()
|
|
293
|
-
reactive(this.
|
|
295
|
+
reactive(this.processShallowReactive(this.props))
|
|
294
296
|
} else {
|
|
295
297
|
this.props = diffAndCloneA(this.target.__getProps(this.options)).clone
|
|
296
|
-
reactive(this.
|
|
298
|
+
reactive(this.processShallowReactive(this.props))
|
|
297
299
|
}
|
|
298
300
|
proxy(this.target, this.props, undefined, false, this.createProxyConflictHandler('props'))
|
|
299
301
|
}
|
|
@@ -333,7 +335,7 @@ export default class MpxProxy {
|
|
|
333
335
|
if (isFunction(dataFn)) {
|
|
334
336
|
Object.assign(this.data, callWithErrorHandling(dataFn.bind(this.target), this, 'data function'))
|
|
335
337
|
}
|
|
336
|
-
reactive(this.
|
|
338
|
+
reactive(this.processShallowReactive(this.data))
|
|
337
339
|
proxy(this.target, this.data, undefined, false, this.createProxyConflictHandler('data'))
|
|
338
340
|
this.collectLocalKeys(this.data)
|
|
339
341
|
}
|
|
@@ -514,7 +516,7 @@ export default class MpxProxy {
|
|
|
514
516
|
if (hasOwn(renderData, key)) {
|
|
515
517
|
const data = renderData[key]
|
|
516
518
|
const firstKey = getFirstKey(key)
|
|
517
|
-
if (!this.localKeysMap[firstKey]
|
|
519
|
+
if (!this.localKeysMap[firstKey]) {
|
|
518
520
|
continue
|
|
519
521
|
}
|
|
520
522
|
// 外部clone,用于只需要clone的场景
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { setByPath } from '@mpxjs/utils'
|
|
1
|
+
import { setByPath, error, parseDataset } from '@mpxjs/utils'
|
|
2
|
+
import Mpx from '../../index'
|
|
2
3
|
|
|
3
4
|
export default function proxyEventMixin () {
|
|
4
5
|
return {
|
|
@@ -19,11 +20,58 @@ export default function proxyEventMixin () {
|
|
|
19
20
|
const value = filterMethod ? (innerFilter[filterMethod] ? innerFilter[filterMethod](originValue) : typeof this[filterMethod] === 'function' && this[filterMethod]) : originValue
|
|
20
21
|
setByPath(this, expr, value)
|
|
21
22
|
},
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
__invoke (rawEvent, eventConfig = []) {
|
|
24
|
+
if (typeof Mpx.config.proxyEventHandler === 'function') {
|
|
25
|
+
try {
|
|
26
|
+
Mpx.config.proxyEventHandler(rawEvent)
|
|
27
|
+
} catch (e) {}
|
|
26
28
|
}
|
|
29
|
+
const location = this.__mpxProxy.options.mpxFileResource
|
|
30
|
+
|
|
31
|
+
if (rawEvent.target && !rawEvent.target._datasetProcessed) {
|
|
32
|
+
const originalDataset = rawEvent.target.dataset
|
|
33
|
+
Object.defineProperty(rawEvent.target, 'dataset', {
|
|
34
|
+
get: () => parseDataset(originalDataset),
|
|
35
|
+
configurable: true,
|
|
36
|
+
enumerable: true
|
|
37
|
+
})
|
|
38
|
+
rawEvent.target._datasetProcessed = true
|
|
39
|
+
}
|
|
40
|
+
if (rawEvent.currentTarget && !rawEvent.currentTarget._datasetProcessed) {
|
|
41
|
+
const originalDataset = rawEvent.currentTarget.dataset
|
|
42
|
+
Object.defineProperty(rawEvent.currentTarget, 'dataset', {
|
|
43
|
+
get: () => parseDataset(originalDataset),
|
|
44
|
+
configurable: true,
|
|
45
|
+
enumerable: true
|
|
46
|
+
})
|
|
47
|
+
rawEvent.currentTarget._datasetProcessed = true
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let returnedValue
|
|
51
|
+
eventConfig.forEach((item) => {
|
|
52
|
+
const callbackName = item[0]
|
|
53
|
+
if (callbackName) {
|
|
54
|
+
const params =
|
|
55
|
+
item.length > 1
|
|
56
|
+
? item.slice(1).map((item) => {
|
|
57
|
+
if (item === '__mpx_event__') {
|
|
58
|
+
return rawEvent
|
|
59
|
+
} else {
|
|
60
|
+
return item
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
: [rawEvent]
|
|
64
|
+
if (typeof this[callbackName] === 'function') {
|
|
65
|
+
returnedValue = this[callbackName].apply(this, params)
|
|
66
|
+
} else {
|
|
67
|
+
error(
|
|
68
|
+
`Instance property [${callbackName}] is not function, please check.`,
|
|
69
|
+
location
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
return returnedValue
|
|
27
75
|
}
|
|
28
76
|
}
|
|
29
77
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import transferOptions from '../core/transferOptions'
|
|
2
2
|
import builtInKeysMap from './patch/builtInKeysMap'
|
|
3
|
-
import { makeMap, spreadProp, getFocusedNavigation, hasOwn
|
|
3
|
+
import { makeMap, spreadProp, getFocusedNavigation, hasOwn } from '@mpxjs/utils'
|
|
4
4
|
import { mergeLifecycle } from '../convertor/mergeLifecycle'
|
|
5
5
|
import { LIFECYCLE } from '../platform/patch/lifecycle/index'
|
|
6
6
|
import Mpx from '../index'
|
|
7
7
|
import { createElement, memo, useRef, useEffect } from 'react'
|
|
8
8
|
import * as ReactNative from 'react-native'
|
|
9
9
|
import { Image } from 'react-native'
|
|
10
|
-
import { ref } from '../observer/ref'
|
|
11
10
|
|
|
12
11
|
const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
|
|
13
12
|
|
|
@@ -30,22 +29,27 @@ function filterOptions (options, appData) {
|
|
|
30
29
|
return newOptions
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
function
|
|
34
|
-
return extend({}, Mpx.prototype, appData)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export default function createApp (option, config = {}) {
|
|
32
|
+
export default function createApp (options) {
|
|
38
33
|
const appData = {}
|
|
39
34
|
|
|
40
35
|
const { NavigationContainer, createStackNavigator, SafeAreaProvider } = global.__navigationHelper
|
|
41
36
|
// app选项目前不需要进行转换
|
|
42
|
-
const { rawOptions, currentInject } = transferOptions(
|
|
37
|
+
const { rawOptions, currentInject } = transferOptions(options, 'app', false)
|
|
43
38
|
const defaultOptions = filterOptions(spreadProp(rawOptions, 'methods'), appData)
|
|
44
|
-
defaultOptions.onAppInit && defaultOptions.onAppInit()
|
|
45
39
|
// 在页面script执行前填充getApp()
|
|
46
40
|
global.getApp = function () {
|
|
47
41
|
return appData
|
|
48
42
|
}
|
|
43
|
+
|
|
44
|
+
// 模拟小程序appInstance在热启动时不会重新创建的行为,在外部创建跟随js context的appInstance
|
|
45
|
+
const appInstance = Object.assign({}, appData, Mpx.prototype)
|
|
46
|
+
|
|
47
|
+
defaultOptions.onShow && global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(appInstance))
|
|
48
|
+
defaultOptions.onHide && global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(appInstance))
|
|
49
|
+
defaultOptions.onError && global.__mpxAppCbs.error.push(defaultOptions.onError.bind(appInstance))
|
|
50
|
+
defaultOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(appInstance))
|
|
51
|
+
defaultOptions.onAppInit && defaultOptions.onAppInit()
|
|
52
|
+
|
|
49
53
|
const pages = currentInject.getPages() || {}
|
|
50
54
|
const firstPage = currentInject.firstPage
|
|
51
55
|
const Stack = createStackNavigator()
|
|
@@ -82,55 +86,50 @@ export default function createApp (option, config = {}) {
|
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
global.__mpxAppLaunched = false
|
|
85
|
-
|
|
86
|
-
global.__mpxAppFocusedState = ref('show')
|
|
87
89
|
global.__mpxOptionsMap[currentInject.moduleId] = memo((props) => {
|
|
88
|
-
const
|
|
89
|
-
if (!instanceRef.current) {
|
|
90
|
-
instanceRef.current = createAppInstance(appData)
|
|
91
|
-
}
|
|
92
|
-
const instance = instanceRef.current
|
|
90
|
+
const firstRef = useRef(true)
|
|
93
91
|
const initialRouteRef = useRef({
|
|
94
92
|
initialRouteName: firstPage,
|
|
95
93
|
initialParams: {}
|
|
96
94
|
})
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
if (firstRef.current) {
|
|
96
|
+
// 热启动情况下,app会被销毁重建,将__mpxAppHotLaunched重置保障路由等初始化逻辑正确执行
|
|
97
|
+
global.__mpxAppHotLaunched = false
|
|
98
|
+
// 热启动情况下重置__mpxPagesMap避免页面销毁函数未及时执行时错误地引用到之前的navigation
|
|
99
|
+
global.__mpxPagesMap = {}
|
|
100
|
+
firstRef.current = false
|
|
101
|
+
}
|
|
102
|
+
if (!global.__mpxAppHotLaunched) {
|
|
99
103
|
const { initialRouteName, initialParams } = Mpx.config.rnConfig.parseAppProps?.(props) || {}
|
|
100
104
|
initialRouteRef.current.initialRouteName = initialRouteName || initialRouteRef.current.initialRouteName
|
|
101
105
|
initialRouteRef.current.initialParams = initialParams || initialRouteRef.current.initialParams
|
|
102
106
|
|
|
103
107
|
global.__mpxAppOnLaunch = (navigation) => {
|
|
104
|
-
global.__mpxAppLaunched = true
|
|
105
108
|
const state = navigation.getState()
|
|
106
109
|
Mpx.config.rnConfig.onStateChange?.(state)
|
|
107
110
|
const current = state.routes[state.index]
|
|
108
|
-
|
|
111
|
+
const options = {
|
|
109
112
|
path: current.name,
|
|
110
113
|
query: current.params,
|
|
111
114
|
scene: 0,
|
|
112
115
|
shareTicket: '',
|
|
113
|
-
referrerInfo: {}
|
|
116
|
+
referrerInfo: {},
|
|
117
|
+
isLaunch: true
|
|
118
|
+
}
|
|
119
|
+
global.__mpxEnterOptions = options
|
|
120
|
+
if (!global.__mpxAppLaunched) {
|
|
121
|
+
global.__mpxLaunchOptions = options
|
|
122
|
+
defaultOptions.onLaunch && defaultOptions.onLaunch.call(appInstance, options)
|
|
114
123
|
}
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
global.__mpxAppCbs.show.forEach((cb) => {
|
|
125
|
+
cb(options)
|
|
126
|
+
})
|
|
127
|
+
global.__mpxAppLaunched = true
|
|
128
|
+
global.__mpxAppHotLaunched = true
|
|
117
129
|
}
|
|
118
130
|
}
|
|
119
131
|
|
|
120
132
|
useEffect(() => {
|
|
121
|
-
if (defaultOptions.onShow) {
|
|
122
|
-
global.__mpxAppCbs.show.push(defaultOptions.onShow.bind(instance))
|
|
123
|
-
}
|
|
124
|
-
if (defaultOptions.onHide) {
|
|
125
|
-
global.__mpxAppCbs.hide.push(defaultOptions.onHide.bind(instance))
|
|
126
|
-
}
|
|
127
|
-
if (defaultOptions.onError) {
|
|
128
|
-
global.__mpxAppCbs.error.push(defaultOptions.onError.bind(instance))
|
|
129
|
-
}
|
|
130
|
-
if (defaultOptions.onUnhandledRejection) {
|
|
131
|
-
global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(instance))
|
|
132
|
-
}
|
|
133
|
-
|
|
134
133
|
const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => {
|
|
135
134
|
if (currentState === 'active') {
|
|
136
135
|
let options = global.__mpxEnterOptions
|
|
@@ -24,19 +24,29 @@ function filterOptions (options, appData) {
|
|
|
24
24
|
return newOptions
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export default function createApp (
|
|
28
|
-
|
|
27
|
+
export default function createApp (options, config = {}) {
|
|
28
|
+
const appData = {}
|
|
29
|
+
// app选项目前不需要进行转换
|
|
30
|
+
const { rawOptions, currentInject } = transferOptions(options, 'app', false)
|
|
29
31
|
const builtInMixins = [{
|
|
32
|
+
// 在App中挂载mpx对象供周边工具访问,如e2e测试
|
|
30
33
|
getMpx () {
|
|
31
34
|
return Mpx
|
|
32
35
|
}
|
|
33
36
|
}]
|
|
34
|
-
const appData = {}
|
|
35
37
|
if (__mpx_mode__ === 'web') {
|
|
36
38
|
builtInMixins.push({
|
|
39
|
+
beforeCreate () {
|
|
40
|
+
// for vue provide vm access
|
|
41
|
+
Object.assign(this, appData, Mpx.prototype)
|
|
42
|
+
if (isBrowser) {
|
|
43
|
+
rawOptions.onShow && global.__mpxAppCbs.show.push(rawOptions.onShow.bind(this))
|
|
44
|
+
rawOptions.onHide && global.__mpxAppCbs.hide.push(rawOptions.onHide.bind(this))
|
|
45
|
+
rawOptions.onError && global.__mpxAppCbs.error.push(rawOptions.onError.bind(this))
|
|
46
|
+
rawOptions.onUnhandledRejection && global.__mpxAppCbs.rejection.push(rawOptions.onUnhandledRejection.bind(this))
|
|
47
|
+
}
|
|
48
|
+
},
|
|
37
49
|
created () {
|
|
38
|
-
Object.assign(this, Mpx.prototype)
|
|
39
|
-
Object.assign(this, appData)
|
|
40
50
|
const current = this.$root.$options?.router?.currentRoute || {}
|
|
41
51
|
const options = {
|
|
42
52
|
path: current.path && current.path.replace(/^\//, ''),
|
|
@@ -45,48 +55,36 @@ export default function createApp (option, config = {}) {
|
|
|
45
55
|
shareTicket: '',
|
|
46
56
|
referrerInfo: {}
|
|
47
57
|
}
|
|
58
|
+
// web不分冷启动和热启动
|
|
48
59
|
global.__mpxEnterOptions = options
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
if (this.$options.onHide) {
|
|
56
|
-
global.__mpxAppCbs.hide.push(this.$options.onHide.bind(this))
|
|
57
|
-
}
|
|
58
|
-
if (this.$options.onError) {
|
|
59
|
-
global.__mpxAppCbs.error.push(this.$options.onError.bind(this))
|
|
60
|
-
}
|
|
61
|
-
if (this.$options.onUnhandledRejection) {
|
|
62
|
-
global.__mpxAppCbs.rejection.push(this.$options.onUnhandledRejection.bind(this))
|
|
63
|
-
}
|
|
64
|
-
}
|
|
60
|
+
global.__mpxLaunchOptions = options
|
|
61
|
+
rawOptions.onLaunch && rawOptions.onLaunch.call(this, options)
|
|
62
|
+
global.__mpxAppCbs.show.forEach((cb) => {
|
|
63
|
+
cb(options)
|
|
64
|
+
})
|
|
65
65
|
}
|
|
66
66
|
})
|
|
67
67
|
} else {
|
|
68
68
|
builtInMixins.push({
|
|
69
69
|
onLaunch () {
|
|
70
70
|
Object.assign(this, Mpx.prototype)
|
|
71
|
+
initAppProvides(rawOptions.provide, this)
|
|
71
72
|
}
|
|
72
73
|
})
|
|
73
74
|
}
|
|
74
|
-
// app选项目前不需要进行转换
|
|
75
|
-
const { rawOptions, currentInject } = transferOptions(option, 'app', false)
|
|
76
75
|
rawOptions.mixins = builtInMixins
|
|
77
76
|
const defaultOptions = filterOptions(spreadProp(mergeOptions(rawOptions, 'app', false), 'methods'), appData)
|
|
78
77
|
|
|
79
78
|
if (__mpx_mode__ === 'web') {
|
|
80
|
-
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
|
|
81
|
-
global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
|
|
82
79
|
global.getApp = function () {
|
|
83
80
|
if (!isBrowser) {
|
|
84
81
|
console.error('[Mpx runtime error]: Dangerous API! global.getApp method is running in non browser environments')
|
|
85
82
|
}
|
|
86
83
|
return appData
|
|
87
84
|
}
|
|
85
|
+
global.__mpxOptionsMap = global.__mpxOptionsMap || {}
|
|
86
|
+
global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
|
|
88
87
|
} else {
|
|
89
|
-
initAppProvides(rawOptions)
|
|
90
88
|
defaultOptions.onAppInit && defaultOptions.onAppInit()
|
|
91
89
|
const ctor = config.customCtor || global.currentCtor || App
|
|
92
90
|
ctor(defaultOptions)
|
|
@@ -11,57 +11,60 @@ function extendEvent (e, extendObj = {}) {
|
|
|
11
11
|
})
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.isTouchDevice = document && ('ontouchstart' in document.documentElement)
|
|
14
|
+
function createMpxEvent (layer) {
|
|
15
|
+
let startTimer = null
|
|
16
|
+
let needTap = true
|
|
17
|
+
let touchStartX = 0
|
|
18
|
+
let touchStartY = 0
|
|
19
|
+
let targetElement = null
|
|
20
|
+
const isTouchDevice = document && 'ontouchstart' in document.documentElement
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
const onTouchStart = (event) => {
|
|
24
23
|
if (event.targetTouches?.length > 1) {
|
|
25
24
|
return true
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
const touches = event.targetTouches
|
|
27
|
+
targetElement = event.target
|
|
28
|
+
needTap = true
|
|
29
|
+
startTimer = null
|
|
30
|
+
touchStartX = touches[0].pageX
|
|
31
|
+
touchStartY = touches[0].pageY
|
|
32
|
+
startTimer = setTimeout(() => {
|
|
33
|
+
needTap = false
|
|
34
|
+
sendEvent(targetElement, 'longpress', event)
|
|
35
|
+
sendEvent(targetElement, 'longtap', event)
|
|
37
36
|
}, 350)
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
const onTouchMove = (event) => {
|
|
41
40
|
const touch = event.changedTouches[0]
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
if (
|
|
42
|
+
Math.abs(touch.pageX - touchStartX) > 1 ||
|
|
43
|
+
Math.abs(touch.pageY - touchStartY) > 1
|
|
44
|
+
) {
|
|
45
|
+
needTap = false
|
|
46
|
+
startTimer && clearTimeout(startTimer)
|
|
47
|
+
startTimer = null
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
const onTouchEnd = (event) => {
|
|
50
52
|
if (event.targetTouches?.length > 1) {
|
|
51
53
|
return true
|
|
52
54
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (
|
|
56
|
-
|
|
55
|
+
startTimer && clearTimeout(startTimer)
|
|
56
|
+
startTimer = null
|
|
57
|
+
if (needTap) {
|
|
58
|
+
sendEvent(targetElement, 'tap', event)
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
const onClick = (event) => {
|
|
63
|
+
targetElement = event.target
|
|
64
|
+
sendEvent(targetElement, 'tap', event)
|
|
63
65
|
}
|
|
64
|
-
|
|
66
|
+
|
|
67
|
+
const sendEvent = (targetElement, type, event) => {
|
|
65
68
|
const touchEvent = new CustomEvent(type, {
|
|
66
69
|
bubbles: true,
|
|
67
70
|
cancelable: true
|
|
@@ -72,7 +75,6 @@ function MpxEvent (layer) {
|
|
|
72
75
|
changedTouches,
|
|
73
76
|
touches: changedTouches,
|
|
74
77
|
detail: {
|
|
75
|
-
// pc端点击事件可能没有changedTouches,所以直接从 event中取
|
|
76
78
|
x: changedTouches[0]?.pageX || event.pageX || 0,
|
|
77
79
|
y: changedTouches[0]?.pageY || event.pageY || 0
|
|
78
80
|
}
|
|
@@ -80,28 +82,23 @@ function MpxEvent (layer) {
|
|
|
80
82
|
targetElement && targetElement.dispatchEvent(touchEvent)
|
|
81
83
|
}
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
layer.addEventListener('click', this.onClick, true)
|
|
90
|
-
}
|
|
85
|
+
if (isTouchDevice) {
|
|
86
|
+
layer.addEventListener('touchstart', onTouchStart, true)
|
|
87
|
+
layer.addEventListener('touchmove', onTouchMove, true)
|
|
88
|
+
layer.addEventListener('touchend', onTouchEnd, true)
|
|
89
|
+
} else {
|
|
90
|
+
layer.addEventListener('click', onClick, true)
|
|
91
91
|
}
|
|
92
|
-
this.addListener()
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
export function initEvent () {
|
|
96
95
|
if (isBrowser && !global.__mpxCreatedEvent) {
|
|
97
96
|
global.__mpxCreatedEvent = true
|
|
98
97
|
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
|
99
|
-
|
|
100
|
-
new MpxEvent(document.body)
|
|
98
|
+
createMpxEvent(document.body)
|
|
101
99
|
} else {
|
|
102
100
|
document.addEventListener('DOMContentLoaded', function () {
|
|
103
|
-
|
|
104
|
-
new MpxEvent(document.body)
|
|
101
|
+
createMpxEvent(document.body)
|
|
105
102
|
}, false)
|
|
106
103
|
}
|
|
107
104
|
}
|
|
@@ -60,17 +60,23 @@ export default function install (Vue) {
|
|
|
60
60
|
data: {
|
|
61
61
|
get () {
|
|
62
62
|
return Object.assign({}, this.$props, this.$data)
|
|
63
|
-
}
|
|
63
|
+
},
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true
|
|
64
66
|
},
|
|
65
67
|
dataset: {
|
|
66
68
|
get () {
|
|
67
69
|
return collectDataset(this.$attrs, true)
|
|
68
|
-
}
|
|
70
|
+
},
|
|
71
|
+
enumerable: true,
|
|
72
|
+
configurable: true
|
|
69
73
|
},
|
|
70
74
|
id: {
|
|
71
75
|
get () {
|
|
72
76
|
return this.$attrs.id || ''
|
|
73
|
-
}
|
|
77
|
+
},
|
|
78
|
+
enumerable: true,
|
|
79
|
+
configurable: true
|
|
74
80
|
}
|
|
75
81
|
})
|
|
76
82
|
|
|
@@ -11,11 +11,10 @@ const providesMap = {
|
|
|
11
11
|
global.__mpxProvidesMap = providesMap
|
|
12
12
|
|
|
13
13
|
/** @internal createApp() 初始化应用层 scope provide */
|
|
14
|
-
export function initAppProvides (
|
|
15
|
-
const provideOpt = appOptions.provide
|
|
14
|
+
export function initAppProvides (provideOpt, instance) {
|
|
16
15
|
if (provideOpt) {
|
|
17
16
|
const provided = isFunction(provideOpt)
|
|
18
|
-
? callWithErrorHandling(provideOpt.bind(
|
|
17
|
+
? callWithErrorHandling(provideOpt.bind(instance), instance, 'createApp provide function')
|
|
19
18
|
: provideOpt
|
|
20
19
|
if (isObject(provided)) {
|
|
21
20
|
providesMap.__app = provided
|
|
@@ -365,14 +365,10 @@ function usePageStatus (navigation, pageId) {
|
|
|
365
365
|
const blurSubscription = navigation.addListener('blur', () => {
|
|
366
366
|
pageStatusMap[pageId] = 'hide'
|
|
367
367
|
})
|
|
368
|
-
const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => {
|
|
369
|
-
pageStatusMap[pageId] = value
|
|
370
|
-
})
|
|
371
368
|
|
|
372
369
|
return () => {
|
|
373
370
|
focusSubscription()
|
|
374
371
|
blurSubscription()
|
|
375
|
-
unWatchAppFocusedState()
|
|
376
372
|
del(pageStatusMap, pageId)
|
|
377
373
|
}
|
|
378
374
|
}, [navigation])
|
|
@@ -442,10 +438,17 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
|
|
|
442
438
|
|
|
443
439
|
useEffect(() => {
|
|
444
440
|
if (type === 'page') {
|
|
445
|
-
if (!global.
|
|
441
|
+
if (!global.__mpxAppHotLaunched && global.__mpxAppOnLaunch) {
|
|
446
442
|
global.__mpxAppOnLaunch(props.navigation)
|
|
447
443
|
}
|
|
448
|
-
|
|
444
|
+
const loadParams = {}
|
|
445
|
+
// 此处拿到的props.route.params内属性的value被进行过了一次decode, 不符合预期,此处额外进行一次encode来与微信对齐
|
|
446
|
+
if (isObject(props.route.params)) {
|
|
447
|
+
for (const key in props.route.params) {
|
|
448
|
+
loadParams[key] = encodeURIComponent(props.route.params[key])
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
proxy.callHook(ONLOAD, [loadParams])
|
|
449
452
|
}
|
|
450
453
|
proxy.mounted()
|
|
451
454
|
return () => {
|
|
@@ -23,13 +23,11 @@ function transformProperties (properties) {
|
|
|
23
23
|
} else {
|
|
24
24
|
newFiled = Object.assign({}, rawFiled)
|
|
25
25
|
}
|
|
26
|
-
const rawObserver = rawFiled?.observer
|
|
27
26
|
newFiled.observer = function (value, oldValue) {
|
|
28
27
|
if (this.__mpxProxy) {
|
|
29
28
|
this[key] = value
|
|
30
29
|
this.__mpxProxy.propsUpdated()
|
|
31
30
|
}
|
|
32
|
-
rawObserver && rawObserver.call(this, value, oldValue)
|
|
33
31
|
}
|
|
34
32
|
newProps[key] = newFiled
|
|
35
33
|
})
|