@mpxjs/core 2.10.16 → 2.10.17-beta.2
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 +4 -1
- package/@types/index.d.ts +24 -28
- package/package.json +7 -3
- package/src/convertor/convertor.js +3 -1
- package/src/convertor/getConvertMode.js +2 -1
- package/src/convertor/wxToAli.js +1 -1
- package/src/convertor/wxToKs.js +21 -0
- package/src/convertor/wxToReact.js +1 -1
- package/src/convertor/wxToSwan.js +1 -1
- package/src/convertor/wxToTt.js +1 -1
- package/src/convertor/wxToWeb.js +9 -2
- package/src/core/proxy.js +14 -2
- package/src/core/transferOptions.js +1 -1
- package/src/helper/MpxScroll/index.js +17 -5
- package/src/platform/builtInMixins/index.js +7 -3
- package/src/platform/builtInMixins/pageStatusMixin.js +14 -2
- package/src/platform/builtInMixins/refsMixin.js +47 -46
- package/src/platform/builtInMixins/renderHelperMixin.js +40 -38
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +107 -29
- package/src/platform/createApp.ios.js +10 -24
- package/src/platform/patch/getDefaultOptions.ios.js +69 -45
- package/LICENSE +0 -433
- package/src/platform/env/nav.js +0 -137
package/@types/global.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// declaration for mpx mode
|
|
2
|
-
declare let __mpx_mode__: 'wx' | 'ali' | 'swan' | 'qq' | 'tt' | 'web' | 'dd' | 'qa' | 'jd' | 'android' | 'ios' | 'harmony'
|
|
2
|
+
declare let __mpx_mode__: 'wx' | 'ali' | 'swan' | 'qq' | 'tt' | 'web' | 'dd' | 'qa' | 'jd' | 'android' | 'ios' | 'harmony' | 'ks'
|
|
3
3
|
|
|
4
4
|
// declaration for mpx env
|
|
5
5
|
declare let __mpx_env__: string
|
|
@@ -11,3 +11,6 @@ declare module '*?resolve' {
|
|
|
11
11
|
const resourcePath: string
|
|
12
12
|
export default resourcePath
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
declare let setAppShow: () => void
|
|
16
|
+
declare let setAppHide: () => void
|
package/@types/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import type { GetComputedType } from '@mpxjs/store'
|
|
11
11
|
import type { ScaledSize } from 'react-native'
|
|
12
|
+
import type { ComponentType } from 'react'
|
|
12
13
|
export * from '@mpxjs/store'
|
|
13
14
|
|
|
14
15
|
// utils
|
|
@@ -126,9 +127,17 @@ interface Context {
|
|
|
126
127
|
type ExtendedComponentOptions = {
|
|
127
128
|
disconnectOnUnmounted?: boolean
|
|
128
129
|
shallowReactivePattern?: RegExp
|
|
130
|
+
/**
|
|
131
|
+
* 是否禁用render函数的useMemo,仅输出RN支持
|
|
132
|
+
*/
|
|
133
|
+
disableMemo?: boolean
|
|
129
134
|
} & WechatMiniprogram.Component.ComponentOptions
|
|
130
135
|
|
|
131
136
|
interface ComponentOpt<D extends Data, P extends Properties, C, M extends Methods, Mi extends Array<any>, S extends Record<any, any>> extends Partial<WechatMiniprogram.Component.Lifetimes & WechatMiniprogram.Component.OtherOption> {
|
|
137
|
+
/**
|
|
138
|
+
* ReactNative 原生组件注册
|
|
139
|
+
*/
|
|
140
|
+
components?: Record<string, ComponentType>,
|
|
132
141
|
data?: D
|
|
133
142
|
properties?: P
|
|
134
143
|
computed?: C
|
|
@@ -221,7 +230,7 @@ type WxComponentIns<D extends Data = {}, P extends Properties = {}, M extends Me
|
|
|
221
230
|
Omit<WechatMiniprogram.Component.Instance<D, P, M>, 'selectComponent' | 'selectAllComponents'>
|
|
222
231
|
& ReplaceWxComponentIns
|
|
223
232
|
|
|
224
|
-
type ComponentIns<D extends Data = {}, P extends Properties = {}, C = {}, M extends Methods = {}, Mi extends Array<any> = [], S extends Record<any, any> = {}, O = {}> =
|
|
233
|
+
export type ComponentIns<D extends Data = {}, P extends Properties = {}, C = {}, M extends Methods = {}, Mi extends Array<any> = [], S extends Record<any, any> = {}, O = {}> =
|
|
225
234
|
GetDataType<D> & UnboxMixinsField<Mi, 'data'> &
|
|
226
235
|
M & UnboxMixinsField<Mi, 'methods'> & { [K in keyof S]: S[K] extends Ref<infer V> ? V : S[K] } &
|
|
227
236
|
GetPropsType<P & UnboxMixinsField<Mi, 'properties'>> &
|
|
@@ -296,7 +305,7 @@ export interface RnConfig {
|
|
|
296
305
|
* - `true`:允许退出应用
|
|
297
306
|
* - `false`:阻止退出应用
|
|
298
307
|
*/
|
|
299
|
-
onAppBack?: () => boolean
|
|
308
|
+
onAppBack?: (delta: number) => boolean
|
|
300
309
|
|
|
301
310
|
/**
|
|
302
311
|
* 是否禁用框架内部的 AppStateChange 监听。
|
|
@@ -356,26 +365,6 @@ export interface RnConfig {
|
|
|
356
365
|
dimensions: T
|
|
357
366
|
) => T | void
|
|
358
367
|
|
|
359
|
-
/**
|
|
360
|
-
* 异步分包加载配置。
|
|
361
|
-
*/
|
|
362
|
-
asyncChunk?: {
|
|
363
|
-
/**
|
|
364
|
-
* 加载超时时长配置,单位为毫秒。
|
|
365
|
-
*/
|
|
366
|
-
timeout: number
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* 异步分包页面加载超时或失败时,自定义兜底页面文件路径。
|
|
370
|
-
*/
|
|
371
|
-
fallback: string
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* 异步分包页面加载时,自定义 loading 页面文件路径。
|
|
375
|
-
*/
|
|
376
|
-
loading: string
|
|
377
|
-
}
|
|
378
|
-
|
|
379
368
|
/**
|
|
380
369
|
* 加载并执行异步分包的方法。
|
|
381
370
|
*
|
|
@@ -392,6 +381,13 @@ export interface RnConfig {
|
|
|
392
381
|
* @param packages 分包名数组
|
|
393
382
|
*/
|
|
394
383
|
downloadChunkAsync?: (packages: Array<string>) => void
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* bundle 中是否关闭 android 键盘避让功能,如果关闭需要将该配置设置为 false,使用 mpx 内置的键盘避让逻辑
|
|
387
|
+
* @platform android
|
|
388
|
+
* @default true
|
|
389
|
+
*/
|
|
390
|
+
enableNativeKeyboardAvoiding?: boolean
|
|
395
391
|
}
|
|
396
392
|
|
|
397
393
|
interface MpxConfig {
|
|
@@ -399,10 +395,10 @@ interface MpxConfig {
|
|
|
399
395
|
ignoreWarning: boolean | string | RegExp | ((msg: string, location: string, e: Error) => boolean)
|
|
400
396
|
ignoreProxyWhiteList: Array<string>
|
|
401
397
|
observeClassInstance: boolean | Array<AnyConstructor>
|
|
402
|
-
errorHandler: (msg: String, location: String, e: Error) =>
|
|
403
|
-
warnHandler: (msg: String, location: String, e: Error) =>
|
|
404
|
-
proxyEventHandler: (e: WechatMiniprogram.CustomEvent, target: ComponentIns<{}, {}, {}, {}, []>) =>
|
|
405
|
-
setDataHandler: (data: object, target: ComponentIns<{}, {}, {}, {}, []>) =>
|
|
398
|
+
errorHandler: (msg: String, location: String, e: Error) => void
|
|
399
|
+
warnHandler: (msg: String, location: String, e: Error) => void
|
|
400
|
+
proxyEventHandler: (e: WechatMiniprogram.CustomEvent, target: ComponentIns<{}, {}, {}, {}, []>) => void
|
|
401
|
+
setDataHandler: (data: object, target: ComponentIns<{}, {}, {}, {}, []>) => void
|
|
406
402
|
forceFlushSync: boolean,
|
|
407
403
|
webRouteConfig: object,
|
|
408
404
|
webConfig: object,
|
|
@@ -413,10 +409,10 @@ interface MpxConfig {
|
|
|
413
409
|
*/
|
|
414
410
|
webviewConfig: WebviewConfig,
|
|
415
411
|
/** react-native 相关配置,用于挂载事件等,如 onShareAppMessage */
|
|
416
|
-
rnConfig
|
|
412
|
+
rnConfig: RnConfig,
|
|
417
413
|
}
|
|
418
414
|
|
|
419
|
-
type SupportedMode = 'wx' | 'ali' | 'qq' | 'swan' | 'tt' | 'web' | 'qa'
|
|
415
|
+
type SupportedMode = 'wx' | 'ali' | 'qq' | 'swan' | 'tt' | 'web' | 'qa'| 'ks' | 'jd' | 'dd'
|
|
420
416
|
|
|
421
417
|
interface ImplementOptions {
|
|
422
418
|
modes?: Array<SupportedMode>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/core",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.17-beta.2",
|
|
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.10.
|
|
22
|
+
"@mpxjs/utils": "^2.10.17",
|
|
23
23
|
"lodash": "^4.1.1",
|
|
24
24
|
"miniprogram-api-typings": "^3.10.0"
|
|
25
25
|
},
|
|
@@ -93,6 +93,10 @@
|
|
|
93
93
|
"optional": true
|
|
94
94
|
}
|
|
95
95
|
},
|
|
96
|
+
"devDependencies": {
|
|
97
|
+
"@types/react": "^18.2.79",
|
|
98
|
+
"react-native": "^0.74.5"
|
|
99
|
+
},
|
|
96
100
|
"publishConfig": {
|
|
97
101
|
"registry": "https://registry.npmjs.org",
|
|
98
102
|
"access": "public"
|
|
@@ -109,5 +113,5 @@
|
|
|
109
113
|
"url": "https://github.com/didi/mpx/issues"
|
|
110
114
|
},
|
|
111
115
|
"sideEffects": false,
|
|
112
|
-
"gitHead": "
|
|
116
|
+
"gitHead": "2d37697869b9bdda3efab92dda8c910b68fd05c0"
|
|
113
117
|
}
|
|
@@ -9,6 +9,7 @@ import wxToTtRule from './wxToTt'
|
|
|
9
9
|
import wxToDdRule from './wxToDd'
|
|
10
10
|
import wxToJdRule from './wxToJd'
|
|
11
11
|
import wxToReactRule from './wxToReact'
|
|
12
|
+
import wxToKsRule from './wxToKs'
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* 转换规则包含四点
|
|
@@ -38,7 +39,8 @@ const rulesMap = {
|
|
|
38
39
|
wxToJd: extend({}, defaultConvertRule, wxToJdRule),
|
|
39
40
|
wxToIos: extend({}, defaultConvertRule, wxToReactRule),
|
|
40
41
|
wxToAndroid: extend({}, defaultConvertRule, wxToReactRule),
|
|
41
|
-
wxToHarmony: extend({}, defaultConvertRule, wxToReactRule)
|
|
42
|
+
wxToHarmony: extend({}, defaultConvertRule, wxToReactRule),
|
|
43
|
+
wxToKs: extend({}, defaultConvertRule, wxToKsRule)
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
export function getConvertRule (convertMode) {
|
package/src/convertor/wxToAli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { implemented } from '../core/implement'
|
|
|
7
7
|
const unsupported = ['moved', 'definitionFilter']
|
|
8
8
|
|
|
9
9
|
function convertErrorDesc (key) {
|
|
10
|
-
error(`Options.${key} is not supported in runtime conversion from wx to ali.`, global.currentResource)
|
|
10
|
+
error(`Options.${key} is not supported in runtime conversion from wx to ali.`, global.currentResource || global.currentModuleId)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
function notSupportTip (options) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { error } from '@mpxjs/utils'
|
|
2
|
+
|
|
3
|
+
const BEHAVIORS_MAP = [
|
|
4
|
+
'wx://form-field',
|
|
5
|
+
'wx://form-field-group',
|
|
6
|
+
'wx://form-field-button',
|
|
7
|
+
'wx://component-export'
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
convert (options) {
|
|
12
|
+
if (options.behaviors) {
|
|
13
|
+
options.behaviors.forEach((behavior, idx) => {
|
|
14
|
+
if (BEHAVIORS_MAP.includes(behavior)) {
|
|
15
|
+
error(`Built-in behavior "${behavior}" is not supported in ks environment!`, global.currentResource || global.currentModuleId)
|
|
16
|
+
options.behaviors.splice(idx, 1)
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -8,7 +8,7 @@ import { implemented } from '../core/implement'
|
|
|
8
8
|
const unsupported = ['moved', 'definitionFilter']
|
|
9
9
|
|
|
10
10
|
function convertErrorDesc (key) {
|
|
11
|
-
error(`Options.${key} is not supported in runtime conversion from wx to react native.`, global.currentResource)
|
|
11
|
+
error(`Options.${key} is not supported in runtime conversion from wx to react native.`, global.currentResource || global.currentModuleId)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
function notSupportTip (options) {
|
|
@@ -12,7 +12,7 @@ const BEHAVIORS_MAP = {
|
|
|
12
12
|
const unsupported = ['moved', 'relations']
|
|
13
13
|
|
|
14
14
|
function convertErrorDesc (key) {
|
|
15
|
-
error(`Options.${key} is not supported in runtime conversion from wx to swan.`, global.currentResource)
|
|
15
|
+
error(`Options.${key} is not supported in runtime conversion from wx to swan.`, global.currentResource || global.currentModuleId)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function notSupportTip (options) {
|
package/src/convertor/wxToTt.js
CHANGED
|
@@ -12,7 +12,7 @@ export default {
|
|
|
12
12
|
if (options.behaviors) {
|
|
13
13
|
options.behaviors.forEach((behavior, idx) => {
|
|
14
14
|
if (BEHAVIORS_MAP.includes(behavior)) {
|
|
15
|
-
error(`Built-in behavior "${behavior}" is not supported in tt environment!`, global.currentResource)
|
|
15
|
+
error(`Built-in behavior "${behavior}" is not supported in tt environment!`, global.currentResource || global.currentModuleId)
|
|
16
16
|
options.behaviors.splice(idx, 1)
|
|
17
17
|
}
|
|
18
18
|
})
|
package/src/convertor/wxToWeb.js
CHANGED
|
@@ -6,7 +6,8 @@ import {
|
|
|
6
6
|
diffAndCloneA,
|
|
7
7
|
error,
|
|
8
8
|
hasOwn,
|
|
9
|
-
isDev
|
|
9
|
+
isDev,
|
|
10
|
+
getDefaultValueByType
|
|
10
11
|
} from '@mpxjs/utils'
|
|
11
12
|
import { implemented } from '../core/implement'
|
|
12
13
|
|
|
@@ -14,7 +15,7 @@ import { implemented } from '../core/implement'
|
|
|
14
15
|
const unsupported = ['moved', 'definitionFilter', 'onShareAppMessage']
|
|
15
16
|
|
|
16
17
|
function convertErrorDesc (key) {
|
|
17
|
-
error(`Options.${key} is not supported in runtime conversion from wx to web.`, global.currentResource)
|
|
18
|
+
error(`Options.${key} is not supported in runtime conversion from wx to web.`, global.currentResource || global.currentModuleId)
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
function notSupportTip (options) {
|
|
@@ -56,6 +57,12 @@ export default {
|
|
|
56
57
|
return diffAndCloneA(prop.value).clone
|
|
57
58
|
}
|
|
58
59
|
: prop.value
|
|
60
|
+
} else {
|
|
61
|
+
// 没有显式设置value时,根据type自动添加默认值,与微信小程序原生行为保持一致
|
|
62
|
+
const defaultValue = getDefaultValueByType(prop.type, 'web')
|
|
63
|
+
if (defaultValue !== undefined) {
|
|
64
|
+
newProp.default = defaultValue
|
|
65
|
+
}
|
|
59
66
|
}
|
|
60
67
|
props[key] = newProp
|
|
61
68
|
} else {
|
package/src/core/proxy.js
CHANGED
|
@@ -31,8 +31,10 @@ import {
|
|
|
31
31
|
wrapMethodsWithErrorHandling,
|
|
32
32
|
warn,
|
|
33
33
|
error,
|
|
34
|
-
getEnvObj
|
|
34
|
+
getEnvObj,
|
|
35
|
+
def
|
|
35
36
|
} from '@mpxjs/utils'
|
|
37
|
+
import { renderHelperDefs } from '../platform/builtInMixins/renderHelperMixin'
|
|
36
38
|
import {
|
|
37
39
|
BEFORECREATE,
|
|
38
40
|
CREATED,
|
|
@@ -190,6 +192,7 @@ export default class MpxProxy {
|
|
|
190
192
|
this.callHook(CREATED)
|
|
191
193
|
|
|
192
194
|
if (!isWeb && !isReact) {
|
|
195
|
+
this.initRenderHelpers()
|
|
193
196
|
this.initRender()
|
|
194
197
|
}
|
|
195
198
|
|
|
@@ -335,7 +338,7 @@ export default class MpxProxy {
|
|
|
335
338
|
createSelectorQuery: this.target.createSelectorQuery ? this.target.createSelectorQuery.bind(this.target) : envObj.createSelectorQuery.bind(envObj),
|
|
336
339
|
createIntersectionObserver: this.target.createIntersectionObserver ? this.target.createIntersectionObserver.bind(this.target) : envObj.createIntersectionObserver.bind(envObj),
|
|
337
340
|
getPageId: this.target.getPageId.bind(this.target),
|
|
338
|
-
getOpenerEventChannel: this.target.getOpenerEventChannel.bind(this.target)
|
|
341
|
+
getOpenerEventChannel: this.target.getOpenerEventChannel ? this.target.getOpenerEventChannel.bind(this.target) : noop
|
|
339
342
|
}
|
|
340
343
|
])
|
|
341
344
|
if (!isObject(setupResult)) {
|
|
@@ -728,6 +731,15 @@ export default class MpxProxy {
|
|
|
728
731
|
this.toggleRecurse(true)
|
|
729
732
|
}
|
|
730
733
|
|
|
734
|
+
initRenderHelpers () {
|
|
735
|
+
if (this.options.__nativeRender__ || __mpx_mode__ !== 'ks') return
|
|
736
|
+
Object.keys(renderHelperDefs).forEach((key) => {
|
|
737
|
+
if (!hasOwn(this.target, key)) {
|
|
738
|
+
def(this.target, key, renderHelperDefs[key])
|
|
739
|
+
}
|
|
740
|
+
})
|
|
741
|
+
}
|
|
742
|
+
|
|
731
743
|
initRender () {
|
|
732
744
|
if (this.options.__nativeRender__) return this.doRender()
|
|
733
745
|
|
|
@@ -13,7 +13,7 @@ export default function transferOptions (options, type, needConvert = true) {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
// 文件编译路径
|
|
16
|
-
options.mpxFileResource = global.currentResource
|
|
16
|
+
options.mpxFileResource = global.currentResource || global.currentModuleId
|
|
17
17
|
// 注入全局写入的mixins,原生模式下不进行注入
|
|
18
18
|
if (!options.__nativeRender__) {
|
|
19
19
|
options = mergeInjectedMixins(options, type)
|
|
@@ -57,8 +57,8 @@ export default class MpxScroll {
|
|
|
57
57
|
const isIntersecting = change.isIntersecting
|
|
58
58
|
this.isIntersecting = isIntersecting
|
|
59
59
|
if (!isIntersecting) {
|
|
60
|
-
// 非 inter section 状态下及时清除
|
|
61
|
-
this.el.style.
|
|
60
|
+
// 非 inter section 状态下及时清除 transform,以免影响正常滚动时元素的 fixed 定位
|
|
61
|
+
this.el.style.transform = ''
|
|
62
62
|
this.pullDownEventRegister && this.pullDownEventRegister.destroy()
|
|
63
63
|
} else {
|
|
64
64
|
this.pullDownEventRegister = new EventRegister(this.el, [
|
|
@@ -103,7 +103,12 @@ export default class MpxScroll {
|
|
|
103
103
|
|
|
104
104
|
transformPage (distance) {
|
|
105
105
|
this.translateY = distance
|
|
106
|
-
|
|
106
|
+
if (distance === 0) {
|
|
107
|
+
// 距离为 0 时移除 transform,避免影响页面 fixed 定位
|
|
108
|
+
this.el.style.transform = ''
|
|
109
|
+
} else {
|
|
110
|
+
this.el.style.transform = `translateY(${distance}px)`
|
|
111
|
+
}
|
|
107
112
|
}
|
|
108
113
|
|
|
109
114
|
onTouchEnd (e) {
|
|
@@ -219,8 +224,15 @@ export default class MpxScroll {
|
|
|
219
224
|
}
|
|
220
225
|
|
|
221
226
|
onReachBottom (onReachBottomDistance, callback) {
|
|
222
|
-
const
|
|
223
|
-
const
|
|
227
|
+
const scrollTop = getScrollTop()
|
|
228
|
+
const scrollHeight = document.documentElement.scrollHeight
|
|
229
|
+
const clientHeight = window.innerHeight
|
|
230
|
+
|
|
231
|
+
// 使用 scrollHeight 判断实际内容高度是否超过视口,只有可滚动时才计算触底
|
|
232
|
+
const scrollable = scrollHeight > clientHeight
|
|
233
|
+
// 距离底部的距离 = 内容总高度 - (当前滚动位置 + 视口高度)
|
|
234
|
+
const distanceToBottom = scrollHeight - (scrollTop + clientHeight)
|
|
235
|
+
const mark = scrollable && (distanceToBottom <= onReachBottomDistance)
|
|
224
236
|
|
|
225
237
|
if (!this.bottomReached && mark) {
|
|
226
238
|
this.bottomReached = true
|
|
@@ -57,14 +57,18 @@ export default function getBuiltInMixins ({ type, rawOptions = {} }) {
|
|
|
57
57
|
}
|
|
58
58
|
// 此为纯增强类mixins,原生模式下不需要注入
|
|
59
59
|
if (!rawOptions.__nativeRender__) {
|
|
60
|
-
|
|
61
|
-
renderHelperMixin(),
|
|
60
|
+
const enhancedMixins = [
|
|
62
61
|
showMixin(type),
|
|
63
62
|
i18nMixin(),
|
|
64
63
|
dynamicRenderHelperMixin(),
|
|
65
64
|
dynamicSlotMixin(),
|
|
66
65
|
dynamicRefsMixin()
|
|
67
|
-
]
|
|
66
|
+
]
|
|
67
|
+
if (__mpx_mode__ !== 'ks') {
|
|
68
|
+
// ks methods 不支持 _ 或者 $ 开头的方法名,所以 ks 不走 methods mixin
|
|
69
|
+
enhancedMixins.unshift(renderHelperMixin())
|
|
70
|
+
}
|
|
71
|
+
bulitInMixins = bulitInMixins.concat(enhancedMixins)
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
74
|
return bulitInMixins.filter(item => item)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CREATED, ONLOAD, ONSHOW, ONHIDE, ONRESIZE } from '../../core/innerLifecycle'
|
|
2
|
+
import { isObject } from '@mpxjs/utils'
|
|
2
3
|
|
|
3
4
|
export default function pageStatusMixin (mixinType) {
|
|
4
5
|
if (mixinType === 'page') {
|
|
@@ -12,8 +13,19 @@ export default function pageStatusMixin (mixinType) {
|
|
|
12
13
|
onResize (e) {
|
|
13
14
|
this.__mpxProxy.callHook(ONRESIZE, [e])
|
|
14
15
|
},
|
|
15
|
-
onLoad (
|
|
16
|
-
|
|
16
|
+
onLoad (rawQuery) {
|
|
17
|
+
if (__mpx_mode__ === 'wx' || __mpx_mode__ === 'qq' || __mpx_mode__ === 'tt') {
|
|
18
|
+
const decodedQuery = {}
|
|
19
|
+
// 处理以上平台直接透传encode的结果,给到onload第二个参数供开发者使用
|
|
20
|
+
if (isObject(rawQuery)) {
|
|
21
|
+
for (const key in rawQuery) {
|
|
22
|
+
decodedQuery[key] = decodeURIComponent(rawQuery[key])
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
this.__mpxProxy.callHook(ONLOAD, [rawQuery, decodedQuery])
|
|
26
|
+
} else {
|
|
27
|
+
this.__mpxProxy.callHook(ONLOAD, [rawQuery, rawQuery])
|
|
28
|
+
}
|
|
17
29
|
}
|
|
18
30
|
}
|
|
19
31
|
if (__mpx_mode__ === 'ali') {
|
|
@@ -15,6 +15,52 @@ const setRef = function (target, ref, isAsync) {
|
|
|
15
15
|
}
|
|
16
16
|
})
|
|
17
17
|
}
|
|
18
|
+
const proxyMethods = ['boundingClientRect', 'scrollOffset']
|
|
19
|
+
function rewriteAliCreateSelectorQuery (target) {
|
|
20
|
+
const rawCreateSelectorQuery = target.createSelectorQuery
|
|
21
|
+
target.createSelectorQuery = function (...args) {
|
|
22
|
+
let selectorQuery = rawCreateSelectorQuery.apply(target, args)
|
|
23
|
+
const cbs = []
|
|
24
|
+
|
|
25
|
+
if (typeof selectorQuery === 'undefined') {
|
|
26
|
+
// 兜底 selectorQuery 在ali为 undefined 情况
|
|
27
|
+
// 调用 createSelectorQuery时,组件实例已经被销毁,ali this._originCreateSelectorQuery 返回 undefined。导致后续 selectorQuery[name] 报错
|
|
28
|
+
// 方案:对齐微信,微信实例销毁时,其他调用正常,仅 createSelectorQuery.exec 不执行回调
|
|
29
|
+
// 复现:setTimeout 中调用,倒计时未回调时切换页面
|
|
30
|
+
selectorQuery = {}
|
|
31
|
+
// ['boundingClientRect', 'context', 'exec', 'fields', 'in', 'node', 'scrollOffset', 'select', 'selectAll', 'selectViewport', 'toImage']
|
|
32
|
+
const backupMethodKeys = Object.keys(envObj.createSelectorQuery())
|
|
33
|
+
const backupFn = function () {
|
|
34
|
+
return selectorQuery
|
|
35
|
+
}
|
|
36
|
+
backupMethodKeys.forEach(key => {
|
|
37
|
+
selectorQuery[key] = backupFn
|
|
38
|
+
})
|
|
39
|
+
return selectorQuery
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
proxyMethods.forEach((name) => {
|
|
43
|
+
const originalMethod = selectorQuery[name]
|
|
44
|
+
selectorQuery[name] = function (cb = noop) {
|
|
45
|
+
cbs.push(cb)
|
|
46
|
+
return originalMethod.call(this)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const originalExec = selectorQuery.exec
|
|
51
|
+
selectorQuery.exec = function (originalCb = noop) {
|
|
52
|
+
const cb = function (results) {
|
|
53
|
+
results.forEach((item, index) => {
|
|
54
|
+
cbs[index] && cbs[index](item)
|
|
55
|
+
})
|
|
56
|
+
originalCb(results)
|
|
57
|
+
}
|
|
58
|
+
return originalExec.call(this, cb)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return selectorQuery
|
|
62
|
+
}
|
|
63
|
+
}
|
|
18
64
|
|
|
19
65
|
export default function getRefsMixin () {
|
|
20
66
|
const refsMixin = {
|
|
@@ -24,8 +70,7 @@ export default function getRefsMixin () {
|
|
|
24
70
|
this.__getRefs()
|
|
25
71
|
|
|
26
72
|
if (__mpx_mode__ === 'ali') {
|
|
27
|
-
this
|
|
28
|
-
this.createSelectorQuery = this._createSelectorQuery
|
|
73
|
+
rewriteAliCreateSelectorQuery(this)
|
|
29
74
|
}
|
|
30
75
|
},
|
|
31
76
|
methods: {
|
|
@@ -68,51 +113,7 @@ export default function getRefsMixin () {
|
|
|
68
113
|
}
|
|
69
114
|
})
|
|
70
115
|
|
|
71
|
-
const proxyMethods = ['boundingClientRect', 'scrollOffset']
|
|
72
|
-
|
|
73
116
|
Object.assign(refsMixin.methods, {
|
|
74
|
-
_createSelectorQuery (...args) {
|
|
75
|
-
let selectorQuery = this._originCreateSelectorQuery(...args)
|
|
76
|
-
const cbs = []
|
|
77
|
-
|
|
78
|
-
if (typeof selectorQuery === 'undefined') {
|
|
79
|
-
// 兜底 selectorQuery 在ali为 undefined 情况
|
|
80
|
-
// 调用 createSelectorQuery时,组件实例已经被销毁,ali this._originCreateSelectorQuery 返回 undefined。导致后续 selectorQuery[name] 报错
|
|
81
|
-
// 方案:对齐微信,微信实例销毁时,其他调用正常,仅 createSelectorQuery.exec 不执行回调
|
|
82
|
-
// 复现:setTimeout 中调用,倒计时未回调时切换页面
|
|
83
|
-
selectorQuery = {}
|
|
84
|
-
// ['boundingClientRect', 'context', 'exec', 'fields', 'in', 'node', 'scrollOffset', 'select', 'selectAll', 'selectViewport', 'toImage']
|
|
85
|
-
const backupMethodKeys = Object.keys(envObj.createSelectorQuery())
|
|
86
|
-
const backupFn = function () {
|
|
87
|
-
return selectorQuery
|
|
88
|
-
}
|
|
89
|
-
backupMethodKeys.forEach(key => {
|
|
90
|
-
selectorQuery[key] = backupFn
|
|
91
|
-
})
|
|
92
|
-
return selectorQuery
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
proxyMethods.forEach((name) => {
|
|
96
|
-
const originalMethod = selectorQuery[name]
|
|
97
|
-
selectorQuery[name] = function (cb = noop) {
|
|
98
|
-
cbs.push(cb)
|
|
99
|
-
return originalMethod.call(this)
|
|
100
|
-
}
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
const originalExec = selectorQuery.exec
|
|
104
|
-
selectorQuery.exec = function (originalCb = noop) {
|
|
105
|
-
const cb = function (results) {
|
|
106
|
-
results.forEach((item, index) => {
|
|
107
|
-
cbs[index] && cbs[index](item)
|
|
108
|
-
})
|
|
109
|
-
originalCb(results)
|
|
110
|
-
}
|
|
111
|
-
return originalExec.call(this, cb)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return selectorQuery
|
|
115
|
-
},
|
|
116
117
|
selectComponent (selector) {
|
|
117
118
|
return this.$selectComponent(selector)
|
|
118
119
|
},
|
|
@@ -1,44 +1,46 @@
|
|
|
1
1
|
import { getByPath, hasOwn, isObject } from '@mpxjs/utils'
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
for (i = 0; i < val; i++) {
|
|
14
|
-
handler.call(this, i + 1, i)
|
|
15
|
-
}
|
|
16
|
-
} else if (isObject(val)) {
|
|
17
|
-
keys = Object.keys(val)
|
|
18
|
-
for (i = 0, l = keys.length; i < l; i++) {
|
|
19
|
-
key = keys[i]
|
|
20
|
-
handler.call(this, val[key], key, i)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
// collect
|
|
25
|
-
_c (key, value) {
|
|
26
|
-
if (hasOwn(this.__mpxProxy.renderData, key)) {
|
|
27
|
-
return this.__mpxProxy.renderData[key]
|
|
28
|
-
}
|
|
29
|
-
if (value === undefined) {
|
|
30
|
-
value = getByPath(this, key)
|
|
31
|
-
}
|
|
32
|
-
this.__mpxProxy.renderData[key] = value
|
|
33
|
-
return value
|
|
34
|
-
},
|
|
35
|
-
// simple collect
|
|
36
|
-
_sc (key) {
|
|
37
|
-
return (this.__mpxProxy.renderData[key] = this[key])
|
|
38
|
-
},
|
|
39
|
-
_r (skipPre, vnode) {
|
|
40
|
-
this.__mpxProxy.renderWithData(skipPre, vnode)
|
|
3
|
+
export const renderHelperDefs = {
|
|
4
|
+
_i (val, handler) {
|
|
5
|
+
let i, l, keys, key
|
|
6
|
+
if (Array.isArray(val) || typeof val === 'string') {
|
|
7
|
+
for (i = 0, l = val.length; i < l; i++) {
|
|
8
|
+
handler.call(this, val[i], i)
|
|
9
|
+
}
|
|
10
|
+
} else if (typeof val === 'number') {
|
|
11
|
+
for (i = 0; i < val; i++) {
|
|
12
|
+
handler.call(this, i + 1, i)
|
|
41
13
|
}
|
|
14
|
+
} else if (isObject(val)) {
|
|
15
|
+
keys = Object.keys(val)
|
|
16
|
+
for (i = 0, l = keys.length; i < l; i++) {
|
|
17
|
+
key = keys[i]
|
|
18
|
+
handler.call(this, val[key], key, i)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
// collect
|
|
23
|
+
_c (key, value) {
|
|
24
|
+
if (hasOwn(this.__mpxProxy.renderData, key)) {
|
|
25
|
+
return this.__mpxProxy.renderData[key]
|
|
26
|
+
}
|
|
27
|
+
if (value === undefined) {
|
|
28
|
+
value = getByPath(this, key)
|
|
42
29
|
}
|
|
30
|
+
this.__mpxProxy.renderData[key] = value
|
|
31
|
+
return value
|
|
32
|
+
},
|
|
33
|
+
// simple collect
|
|
34
|
+
_sc (key) {
|
|
35
|
+
return (this.__mpxProxy.renderData[key] = this[key])
|
|
36
|
+
},
|
|
37
|
+
_r (skipPre, vnode) {
|
|
38
|
+
this.__mpxProxy.renderWithData(skipPre, vnode)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default function renderHelperMixin () {
|
|
43
|
+
return {
|
|
44
|
+
methods: renderHelperDefs
|
|
43
45
|
}
|
|
44
46
|
}
|