@mpxjs/core 2.9.70-alpha.0 → 2.9.70

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.
Files changed (34) hide show
  1. package/@types/global.d.ts +1 -1
  2. package/LICENSE +433 -0
  3. package/package.json +9 -6
  4. package/src/convertor/convertor.js +0 -2
  5. package/src/convertor/getConvertMode.js +0 -1
  6. package/src/core/proxy.js +8 -9
  7. package/src/index.js +3 -14
  8. package/src/observer/reactive.js +4 -3
  9. package/src/platform/builtInMixins/directiveHelperMixin.ios.js +4 -1
  10. package/src/platform/builtInMixins/index.js +0 -5
  11. package/src/platform/builtInMixins/styleHelperMixin.ios.js +1 -1
  12. package/src/platform/createApp.ios.js +24 -23
  13. package/src/platform/createApp.js +5 -14
  14. package/src/platform/env/event.js +108 -0
  15. package/src/platform/env/index.ios.js +51 -0
  16. package/src/platform/env/index.js +8 -0
  17. package/src/platform/env/index.web.js +48 -0
  18. package/src/{external → platform/env}/vuePlugin.js +1 -1
  19. package/src/platform/export/index.js +1 -1
  20. package/src/platform/patch/builtInKeysMap.js +1 -1
  21. package/src/platform/patch/getDefaultOptions.ios.js +9 -13
  22. package/src/platform/patch/index.js +3 -3
  23. package/src/convertor/wxToTenon.js +0 -86
  24. package/src/external/vue.js +0 -1
  25. package/src/external/vue.tenon.js +0 -13
  26. package/src/external/vue.web.js +0 -6
  27. package/src/platform/builtInMixins/pageStatusMixin.tenon.js +0 -40
  28. package/src/platform/builtInMixins/proxyEventMixin.tenon.js +0 -46
  29. package/src/platform/export/apiInject.tenon.js +0 -1
  30. package/src/platform/export/index.tenon.js +0 -78
  31. package/src/platform/patch/getDefaultOptions.tenon.js +0 -99
  32. package/src/platform/patch/lifecycle/index.tenon.js +0 -52
  33. /package/src/platform/export/{apiInject.js → inject.js} +0 -0
  34. /package/src/platform/export/{apiInject.web.js → inject.web.js} +0 -0
@@ -1,11 +1,12 @@
1
1
  import transferOptions from '../core/transferOptions'
2
2
  import builtInKeysMap from './patch/builtInKeysMap'
3
- import { makeMap, spreadProp, parseUrlQuery, getFocusedNavigation, hasOwn, extend } from '@mpxjs/utils'
3
+ import { makeMap, spreadProp, getFocusedNavigation, hasOwn, extend } 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
+ import { Image } from 'react-native'
9
10
  import { ref } from '../observer/ref'
10
11
 
11
12
  const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
@@ -80,12 +81,6 @@ export default function createApp (option, config = {}) {
80
81
  }
81
82
  }
82
83
 
83
- global.__mpxAppCbs = global.__mpxAppCbs || {
84
- show: [],
85
- hide: [],
86
- error: []
87
- }
88
-
89
84
  global.__mpxAppLaunched = false
90
85
 
91
86
  global.__mpxAppFocusedState = ref('show')
@@ -101,14 +96,10 @@ export default function createApp (option, config = {}) {
101
96
  })
102
97
 
103
98
  if (!global.__mpxAppLaunched) {
104
- const parsed = Mpx.config.rnConfig.parseAppProps?.(props) || {}
105
- if (parsed.url) {
106
- const { path, queryObj } = parseUrlQuery(parsed.url)
107
- Object.assign(initialRouteRef.current, {
108
- initialRouteName: path.startsWith('/') ? path.slice(1) : path,
109
- initialParams: queryObj
110
- })
111
- }
99
+ const { initialRouteName, initialParams } = Mpx.config.rnConfig.parseAppProps?.(props) || {}
100
+ initialRouteRef.current.initialRouteName = initialRouteName || initialRouteRef.current.initialRouteName
101
+ initialRouteRef.current.initialParams = initialParams || initialRouteRef.current.initialParams
102
+
112
103
  global.__mpxAppOnLaunch = (navigation) => {
113
104
  global.__mpxAppLaunched = true
114
105
  const state = navigation.getState()
@@ -136,6 +127,9 @@ export default function createApp (option, config = {}) {
136
127
  if (defaultOptions.onError) {
137
128
  global.__mpxAppCbs.error.push(defaultOptions.onError.bind(instance))
138
129
  }
130
+ if (defaultOptions.onUnhandledRejection) {
131
+ global.__mpxAppCbs.rejection.push(defaultOptions.onUnhandledRejection.bind(instance))
132
+ }
139
133
 
140
134
  const changeSubscription = ReactNative.AppState.addEventListener('change', (currentState) => {
141
135
  if (currentState === 'active') {
@@ -158,7 +152,7 @@ export default function createApp (option, config = {}) {
158
152
  if (navigation && hasOwn(global.__mpxPageStatusMap, navigation.pageId)) {
159
153
  global.__mpxPageStatusMap[navigation.pageId] = 'show'
160
154
  }
161
- } else if (currentState === 'inactive') {
155
+ } else if (currentState === 'inactive' || currentState === 'background') {
162
156
  global.__mpxAppCbs.hide.forEach((cb) => {
163
157
  cb()
164
158
  })
@@ -187,6 +181,19 @@ export default function createApp (option, config = {}) {
187
181
  }, [])
188
182
 
189
183
  const { initialRouteName, initialParams } = initialRouteRef.current
184
+ const headerBackImageProps = Mpx.config.rnConfig.headerBackImageProps || null
185
+ const navScreenOpts = {
186
+ // 7.x替换headerBackTitleVisible
187
+ // headerBackButtonDisplayMode: 'minimal',
188
+ headerBackTitleVisible: false,
189
+ // 安卓上会出现初始化时闪现导航条的问题
190
+ headerShown: false
191
+ }
192
+ if (headerBackImageProps) {
193
+ navScreenOpts.headerBackImage = () => {
194
+ return createElement(Image, headerBackImageProps)
195
+ }
196
+ }
190
197
  return createElement(SafeAreaProvider,
191
198
  null,
192
199
  createElement(NavigationContainer,
@@ -197,13 +204,7 @@ export default function createApp (option, config = {}) {
197
204
  createElement(Stack.Navigator,
198
205
  {
199
206
  initialRouteName,
200
- screenOptions: {
201
- gestureEnabled: true,
202
- // 7.x替换headerBackTitleVisible
203
- // headerBackButtonDisplayMode: 'minimal',
204
- headerBackTitleVisible: false,
205
- headerMode: 'float'
206
- }
207
+ screenOptions: navScreenOpts
207
208
  },
208
209
  ...getPageScreens(initialRouteName, initialParams)
209
210
  )
@@ -5,7 +5,7 @@ import { makeMap, spreadProp, isBrowser } from '@mpxjs/utils'
5
5
  import { mergeLifecycle } from '../convertor/mergeLifecycle'
6
6
  import { LIFECYCLE } from '../platform/patch/lifecycle/index'
7
7
  import Mpx from '../index'
8
- import { initAppProvides } from './export/apiInject'
8
+ import { initAppProvides } from './export/inject'
9
9
 
10
10
  const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app)
11
11
 
@@ -47,11 +47,6 @@ export default function createApp (option, config = {}) {
47
47
  }
48
48
  global.__mpxEnterOptions = options
49
49
  this.$options.onLaunch && this.$options.onLaunch.call(this, options)
50
- global.__mpxAppCbs = global.__mpxAppCbs || {
51
- show: [],
52
- hide: [],
53
- error: []
54
- }
55
50
  if (isBrowser) {
56
51
  if (this.$options.onShow) {
57
52
  this.$options.onShow.call(this, options)
@@ -63,16 +58,12 @@ export default function createApp (option, config = {}) {
63
58
  if (this.$options.onError) {
64
59
  global.__mpxAppCbs.error.push(this.$options.onError.bind(this))
65
60
  }
61
+ if (this.$options.onUnhandledRejection) {
62
+ global.__mpxAppCbs.rejection.push(this.$options.onUnhandledRejection.bind(this))
63
+ }
66
64
  }
67
65
  }
68
66
  })
69
- } else if (__mpx_mode__ === 'tenon') {
70
- // todo add tenon mixins
71
- builtInMixins.push({
72
- onLaunch () {
73
- // console.log('tenon mixins')
74
- }
75
- })
76
67
  } else {
77
68
  builtInMixins.push({
78
69
  onLaunch () {
@@ -85,7 +76,7 @@ export default function createApp (option, config = {}) {
85
76
  rawOptions.mixins = builtInMixins
86
77
  const defaultOptions = filterOptions(spreadProp(mergeOptions(rawOptions, 'app', false), 'methods'), appData)
87
78
 
88
- if (__mpx_mode__ === 'web' || __mpx_mode__ === 'tenon') {
79
+ if (__mpx_mode__ === 'web') {
89
80
  global.__mpxOptionsMap = global.__mpxOptionsMap || {}
90
81
  global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
91
82
  global.getApp = function () {
@@ -0,0 +1,108 @@
1
+ import { isBrowser } from '@mpxjs/utils'
2
+
3
+ function extendEvent (e, extendObj = {}) {
4
+ Object.keys(extendObj).forEach((key) => {
5
+ Object.defineProperty(e, key, {
6
+ value: extendObj[key],
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true
10
+ })
11
+ })
12
+ }
13
+
14
+ function MpxEvent (layer) {
15
+ this.targetElement = null
16
+ this.touches = []
17
+ this.touchStartX = 0
18
+ this.touchStartY = 0
19
+ this.startTimer = null
20
+ this.needTap = true
21
+ this.isTouchDevice = document && ('ontouchstart' in document.documentElement)
22
+
23
+ this.onTouchStart = (event) => {
24
+ if (event.targetTouches?.length > 1) {
25
+ return true
26
+ }
27
+ this.touches = event.targetTouches
28
+ this.targetElement = event.target
29
+ this.needTap = true
30
+ this.startTimer = null
31
+ this.touchStartX = this.touches[0].pageX
32
+ this.touchStartY = this.touches[0].pageY
33
+ this.startTimer = setTimeout(() => {
34
+ this.needTap = false
35
+ this.sendEvent(this.targetElement, 'longpress', event)
36
+ this.sendEvent(this.targetElement, 'longtap', event)
37
+ }, 350)
38
+ }
39
+
40
+ this.onTouchMove = (event) => {
41
+ const touch = event.changedTouches[0]
42
+ if (Math.abs(touch.pageX - this.touchStartX) > 1 || Math.abs(touch.pageY - this.touchStartY) > 1) {
43
+ this.needTap = false
44
+ this.startTimer && clearTimeout(this.startTimer)
45
+ this.startTimer = null
46
+ }
47
+ }
48
+
49
+ this.onTouchEnd = (event) => {
50
+ if (event.targetTouches?.length > 1) {
51
+ return true
52
+ }
53
+ this.startTimer && clearTimeout(this.startTimer)
54
+ this.startTimer = null
55
+ if (this.needTap) {
56
+ this.sendEvent(this.targetElement, 'tap', event)
57
+ }
58
+ }
59
+
60
+ this.onClick = (event) => {
61
+ this.targetElement = event.target
62
+ this.sendEvent(this.targetElement, 'tap', event)
63
+ }
64
+ this.sendEvent = (targetElement, type, event) => {
65
+ const touchEvent = new CustomEvent(type, {
66
+ bubbles: true,
67
+ cancelable: true
68
+ })
69
+ const changedTouches = event.changedTouches || []
70
+ extendEvent(touchEvent, {
71
+ timeStamp: event.timeStamp,
72
+ changedTouches,
73
+ touches: changedTouches,
74
+ detail: {
75
+ // pc端点击事件可能没有changedTouches,所以直接从 event中取
76
+ x: changedTouches[0]?.pageX || event.pageX || 0,
77
+ y: changedTouches[0]?.pageY || event.pageY || 0
78
+ }
79
+ })
80
+ targetElement && targetElement.dispatchEvent(touchEvent)
81
+ }
82
+
83
+ this.addListener = () => {
84
+ if (this.isTouchDevice) {
85
+ layer.addEventListener('touchstart', this.onTouchStart, true)
86
+ layer.addEventListener('touchmove', this.onTouchMove, true)
87
+ layer.addEventListener('touchend', this.onTouchEnd, true)
88
+ } else {
89
+ layer.addEventListener('click', this.onClick, true)
90
+ }
91
+ }
92
+ this.addListener()
93
+ }
94
+
95
+ export function initEvent () {
96
+ if (isBrowser && !global.__mpxCreatedEvent) {
97
+ global.__mpxCreatedEvent = true
98
+ if (document.readyState === 'complete' || document.readyState === 'interactive') {
99
+ // eslint-disable-next-line no-new
100
+ new MpxEvent(document.body)
101
+ } else {
102
+ document.addEventListener('DOMContentLoaded', function () {
103
+ // eslint-disable-next-line no-new
104
+ new MpxEvent(document.body)
105
+ }, false)
106
+ }
107
+ }
108
+ }
@@ -0,0 +1,51 @@
1
+ import { createI18n } from '../builtInMixins/i18nMixin'
2
+
3
+ export function init (Mpx) {
4
+ global.__mpx = Mpx
5
+ global.__mpxAppCbs = global.__mpxAppCbs || {
6
+ show: [],
7
+ hide: [],
8
+ error: [],
9
+ rejection: []
10
+ }
11
+ if (global.i18n) {
12
+ Mpx.i18n = createI18n(global.i18n)
13
+ }
14
+ initGlobalErrorHandling()
15
+ }
16
+
17
+ function initGlobalErrorHandling () {
18
+ if (global.ErrorUtils) {
19
+ const defaultHandler = global.ErrorUtils.getGlobalHandler()
20
+ global.ErrorUtils.setGlobalHandler((error, isFatal) => {
21
+ if (global.__mpxAppCbs && global.__mpxAppCbs.error && global.__mpxAppCbs.error.length) {
22
+ global.__mpxAppCbs.error.forEach((cb) => {
23
+ cb(error)
24
+ })
25
+ } else if (defaultHandler) {
26
+ defaultHandler(error, isFatal)
27
+ } else {
28
+ console.error(`${error.name}: ${error.message}\n`)
29
+ }
30
+ })
31
+ }
32
+
33
+ const rejectionTrackingOptions = {
34
+ allRejections: true,
35
+ onUnhandled (id, error) {
36
+ if (global.__mpxAppCbs && global.__mpxAppCbs.rejection && global.__mpxAppCbs.rejection.length) {
37
+ global.__mpxAppCbs.rejection.forEach((cb) => {
38
+ cb(error, id)
39
+ })
40
+ } else {
41
+ console.warn(`UNHANDLED PROMISE REJECTION (id: ${id}): ${error}\n`)
42
+ }
43
+ }
44
+ }
45
+
46
+ if (global?.HermesInternal?.hasPromise?.()) {
47
+ global.HermesInternal?.enablePromiseRejectionTracker?.(rejectionTrackingOptions)
48
+ } else {
49
+ require('promise/setimmediate/rejection-tracking').enable(rejectionTrackingOptions)
50
+ }
51
+ }
@@ -0,0 +1,8 @@
1
+ import { createI18n } from '../builtInMixins/i18nMixin'
2
+
3
+ export function init (Mpx) {
4
+ global.__mpx = Mpx
5
+ if (global.i18n) {
6
+ Mpx.i18n = createI18n(global.i18n)
7
+ }
8
+ }
@@ -0,0 +1,48 @@
1
+ import Vue from 'vue'
2
+ import install from './vuePlugin'
3
+ import { isBrowser, error, warn } from '@mpxjs/utils'
4
+ import { initEvent } from './event'
5
+
6
+ export function init (Mpx) {
7
+ global.__mpx = Mpx
8
+ global.__mpxAppCbs = global.__mpxAppCbs || {
9
+ show: [],
10
+ hide: [],
11
+ error: [],
12
+ rejection: []
13
+ }
14
+ Mpx.__vue = Vue
15
+ Vue.use(install)
16
+ initEvent()
17
+ initGlobalErrorHandling()
18
+ }
19
+
20
+ function initGlobalErrorHandling () {
21
+ Vue.config.errorHandler = (e, vm, info) => {
22
+ error(`Unhandled error occurs${info ? ` during execution of [${info}]` : ''}!`, vm?.__mpxProxy?.options.mpxFileResource, e)
23
+ }
24
+ Vue.config.warnHandler = (msg, vm, trace) => {
25
+ warn(msg, vm?.__mpxProxy?.options.mpxFileResource, trace)
26
+ }
27
+
28
+ if (isBrowser) {
29
+ window.addEventListener('error', (event) => {
30
+ if (global.__mpxAppCbs && global.__mpxAppCbs.error && global.__mpxAppCbs.error.length) {
31
+ global.__mpxAppCbs.error.forEach((cb) => {
32
+ cb(event.error)
33
+ })
34
+ } else {
35
+ console.error(`${event.type}: ${event.message}\n`)
36
+ }
37
+ })
38
+ window.addEventListener('unhandledrejection', (event) => {
39
+ if (global.__mpxAppCbs && global.__mpxAppCbs.rejection && global.__mpxAppCbs.rejection.length) {
40
+ global.__mpxAppCbs.rejection.forEach((cb) => {
41
+ cb(event.reason, event.promise)
42
+ })
43
+ } else {
44
+ console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}\n`)
45
+ }
46
+ })
47
+ }
48
+ }
@@ -1,7 +1,7 @@
1
1
  import { walkChildren, parseSelector, error, hasOwn, collectDataset } from '@mpxjs/utils'
2
2
  import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy'
3
3
  import { EffectScope } from 'vue'
4
- import { PausedState } from '../helper/const'
4
+ import { PausedState } from '../../helper/const'
5
5
 
6
6
  const hackEffectScope = () => {
7
7
  EffectScope.prototype.pause = function () {
@@ -46,4 +46,4 @@ export {
46
46
  export {
47
47
  provide,
48
48
  inject
49
- } from './apiInject'
49
+ } from './inject'
@@ -3,7 +3,7 @@ import { makeMap } from '@mpxjs/utils'
3
3
 
4
4
  let builtInKeys
5
5
 
6
- if (__mpx_mode__ === 'web' || __mpx_mode__ === 'tenon') {
6
+ if (__mpx_mode__ === 'web') {
7
7
  builtInKeys = [
8
8
  'proto',
9
9
  'mixins',
@@ -3,7 +3,7 @@ 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, isArray, getByPath, collectDataset, hump2dash, wrapMethodsWithErrorHandling } from '@mpxjs/utils'
6
+ import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, dash2hump, callWithErrorHandling, wrapMethodsWithErrorHandling } 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'
@@ -52,20 +52,18 @@ function createEffect (proxy, components) {
52
52
  proxy.effect = new ReactiveEffect(() => {
53
53
  // reset instance
54
54
  proxy.target.__resetInstance()
55
- return proxy.target.__injectedRender(innerCreateElement, getComponent)
55
+ return callWithErrorHandling(proxy.target.__injectedRender.bind(proxy.target), proxy, 'render function', [innerCreateElement, getComponent])
56
56
  }, () => queueJob(update), proxy.scope)
57
57
  // render effect允许自触发
58
58
  proxy.toggleRecurse(true)
59
59
  }
60
60
 
61
- function getRootProps (props) {
61
+ function getRootProps (props, validProps) {
62
62
  const rootProps = {}
63
63
  for (const key in props) {
64
- if (hasOwn(props, key)) {
65
- const match = /^(bind|catch|capture-bind|capture-catch|style|enable-var):?(.*?)(?:\.(.*))?$/.exec(key)
66
- if (match) {
67
- rootProps[key] = props[key]
68
- }
64
+ const altKey = dash2hump(key)
65
+ if (!hasOwn(validProps, key) && !hasOwn(validProps, altKey) && key !== 'children') {
66
+ rootProps[key] = props[key]
69
67
  }
70
68
  }
71
69
  return rootProps
@@ -474,7 +472,8 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
474
472
 
475
473
  const root = useMemo(() => proxy.effect.run(), [finalMemoVersion])
476
474
  if (root && root.props.ishost) {
477
- const rootProps = getRootProps(props)
475
+ // 对于组件未注册的属性继承到host节点上,如事件、样式和其他属性等
476
+ const rootProps = getRootProps(props, validProps)
478
477
  rootProps.style = Object.assign({}, root.props.style, rootProps.style)
479
478
  // update root props
480
479
  return cloneElement(root, rootProps)
@@ -560,10 +559,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) {
560
559
  backgroundColor: pageConfig.backgroundColor || '#ffffff'
561
560
  },
562
561
  ref: rootRef,
563
- onLayout,
564
- onTouchStart: () => {
565
- ReactNative.Keyboard.isVisible() && ReactNative.Keyboard.dismiss()
566
- }
562
+ onLayout
567
563
  },
568
564
  createElement(RouteContext.Provider,
569
565
  {
@@ -1,14 +1,14 @@
1
1
  import transferOptions from '../../core/transferOptions'
2
2
  import getBuiltInMixins from '../builtInMixins/index'
3
3
  import { getDefaultOptions } from './getDefaultOptions'
4
- import { error, isReact, isWeb, isTenon } from '@mpxjs/utils'
4
+ import { error, isReact, isWeb } from '@mpxjs/utils'
5
5
 
6
6
  export default function createFactory (type) {
7
7
  return (options = {}, { isNative, customCtor, customCtorType } = {}) => {
8
8
  options.__nativeRender__ = !!isNative
9
9
  options.__type__ = type
10
10
  let ctor
11
- if (!isWeb && !isReact && !isTenon) {
11
+ if (!isWeb && !isReact) {
12
12
  if (customCtor) {
13
13
  ctor = customCtor
14
14
  customCtorType = customCtorType || type
@@ -43,7 +43,7 @@ export default function createFactory (type) {
43
43
  // 将合并后的用户定义的rawOptions传入获取当前应该注入的内建mixins
44
44
  rawOptions.mixins = getBuiltInMixins({ type, rawOptions, currentInject })
45
45
  const defaultOptions = getDefaultOptions({ type, rawOptions, currentInject })
46
- if (isWeb || isReact || isTenon) {
46
+ if (isWeb || isReact) {
47
47
  global.__mpxOptionsMap = global.__mpxOptionsMap || {}
48
48
  global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions
49
49
  } else if (ctor) {
@@ -1,86 +0,0 @@
1
- import * as wxLifecycle from '../platform/patch/lifecycle/index.wx'
2
- import * as tenonLifecycle from '../platform/patch/lifecycle/index.tenon'
3
- import { mergeLifecycle } from './mergeLifecycle'
4
- import { error, isObject, diffAndCloneA, hasOwn } from '@mpxjs/utils'
5
- import { implemented } from '../core/implement'
6
- import { CREATED, UNMOUNTED } from '../core/innerLifecycle'
7
-
8
- // 暂不支持的wx选项,后期需要各种花式支持
9
- const unsupported = [
10
- 'moved',
11
- 'definitionFilter',
12
- 'onShareAppMessage',
13
- 'activated',
14
- 'deactivated',
15
- 'pageShow',
16
- 'pageHide',
17
- 'onPullDownRefresh',
18
- 'onReachBottom',
19
- 'onPageScroll',
20
- 'onTabItemTap',
21
- 'onResize',
22
- 'onUnhandledRejection',
23
- 'onThemeChange'
24
- ]
25
-
26
- function convertErrorDesc (key) {
27
- error(`Options.${key} is not supported in runtime conversion from wx to tenon.`, global.currentResource)
28
- }
29
-
30
- function notSupportTip (options) {
31
- unsupported.forEach(key => {
32
- if (options[key]) {
33
- if (!implemented[key]) {
34
- process.env.NODE_ENV !== 'production' && convertErrorDesc(key)
35
- delete options[key]
36
- } else if (implemented[key].remove) {
37
- delete options[key]
38
- }
39
- }
40
- })
41
- }
42
-
43
- export default {
44
- lifecycle: mergeLifecycle(wxLifecycle.LIFECYCLE),
45
- lifecycle2: mergeLifecycle(tenonLifecycle.LIFECYCLE),
46
- pageMode: 'blend',
47
- // support传递为true以将methods外层的方法函数合入methods中
48
- support: true,
49
- // wx输出tenon时额外将onLoad代理到CREATED
50
- lifecycleProxyMap: Object.assign({}, wxLifecycle.lifecycleProxyMap, {
51
- [CREATED]: ['created', 'attached', 'onLoad'],
52
- [UNMOUNTED]: ['destroyed', 'detached', 'onUnload', 'unmounted']
53
- }),
54
- convert (options) {
55
- const props = Object.assign({}, options.properties, options.props)
56
- if (props) {
57
- Object.keys(props).forEach(key => {
58
- const prop = props[key]
59
- if (prop) {
60
- if (hasOwn(prop, 'type')) {
61
- const newProp = {}
62
- if (hasOwn(prop, 'optionalTypes')) {
63
- newProp.type = [prop.type, ...prop.optionalTypes]
64
- } else {
65
- newProp.type = prop.type
66
- }
67
- if (hasOwn(prop, 'value')) {
68
- // vue中对于引用类型数据需要使用函数返回
69
- newProp.default = isObject(prop.value)
70
- ? function propFn () {
71
- return diffAndCloneA(prop.value).clone
72
- }
73
- : prop.value
74
- }
75
- props[key] = newProp
76
- } else {
77
- props[key] = prop
78
- }
79
- }
80
- })
81
- options.props = props
82
- delete options.properties
83
- }
84
- notSupportTip(options)
85
- }
86
- }
@@ -1 +0,0 @@
1
- export default {}
@@ -1,13 +0,0 @@
1
- import {
2
- reactive,
3
- computed,
4
- toRaw,
5
- watch
6
- } from '@hummer/tenon-vue'
7
-
8
- export default {
9
- reactive,
10
- computed,
11
- toRaw,
12
- watch
13
- }
@@ -1,6 +0,0 @@
1
- import Vue from 'vue'
2
- import install from './vuePlugin'
3
-
4
- Vue.use(install)
5
-
6
- export default Vue
@@ -1,40 +0,0 @@
1
- import { CREATED, ONSHOW, ONHIDE } from '../../core/innerLifecycle'
2
-
3
- export default function pageStatusMixin (mixinType) {
4
- if (mixinType === 'page') {
5
- return {
6
- data: {
7
- mpxPageStatus: 'show'
8
- },
9
- onShow () {
10
- this.mpxPageStatus = 'show'
11
- this.__mpxProxy.callHook(ONSHOW)
12
- },
13
- onHide () {
14
- this.mpxPageStatus = 'hide'
15
- this.__mpxProxy.callHook(ONHIDE)
16
- },
17
- onBack () {
18
- return this.onBack && this.onBack()
19
- }
20
- }
21
- }
22
- // components
23
- return {
24
- [CREATED] () {
25
- const pageInstance = global.__currentPageInstance
26
- if (!pageInstance) return
27
- this.$watch(
28
- () => pageInstance.mpxPageStatus,
29
- status => {
30
- if (!status) return
31
- const pageLifetimes = (this.$rawOptions && this.$rawOptions.pageLifetimes) || {}
32
- // show & hide
33
- if (status in pageLifetimes && typeof pageLifetimes[status] === 'function') {
34
- pageLifetimes[status].call(this)
35
- }
36
- }
37
- )
38
- }
39
- }
40
- }
@@ -1,46 +0,0 @@
1
- import { setByPath } from '@mpxjs/utils'
2
-
3
- export default function proxyEventMixin () {
4
- const methods = {
5
- triggerEvent (eventName, eventDetail) {
6
- return this.$emit(eventName, {
7
- type: eventName,
8
- detail: eventDetail
9
- })
10
- },
11
- __model (expr, $event, valuePath = ['value'], filterMethod) {
12
- const innerFilter = {
13
- trim: val => typeof val === 'string' && val.trim()
14
- }
15
- const originValue = valuePath.reduce((acc, cur) => acc[cur], $event.detail)
16
- const value = filterMethod ? (innerFilter[filterMethod] ? innerFilter[filterMethod](originValue) : typeof this[filterMethod] === 'function' && this[filterMethod]) : originValue
17
- setByPath(this, expr, value)
18
- },
19
- getOpenerEventChannel () {
20
- const router = global.__mpxRouter
21
- const eventChannel = router && router.__mpxAction && router.__mpxAction.eventChannel
22
- return eventChannel
23
- }
24
- }
25
-
26
- return {
27
- beforeCreate () {
28
- const modelEvent = this.$attrs.mpxModelEvent
29
- const modelEventId = this.$attrs.mpxModelEventId
30
- if (modelEvent && modelEventId) {
31
- Hummer.notifyCenter.addEventListener(modelEventId, (e) => {
32
- this.$emit('mpxModel', e)
33
- })
34
- }
35
- },
36
- beforeDestroy () {
37
- const modelEvent = this.$attrs.mpxModelEvent
38
- const modelEventId = this.$attrs.mpxModelEventId
39
- if (modelEvent && modelEventId) {
40
- Hummer.notifyCenter.removeEventListener(modelEventId)
41
- }
42
- },
43
-
44
- methods
45
- }
46
- }
@@ -1 +0,0 @@
1
- export { provide, inject } from '@hummer/tenon-vue'