From b2a9df569a1da8c7c407a04a7e8e35141f2e202f Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Tue, 10 Dec 2024 14:47:08 +0800 Subject: [PATCH] refactor platform/patch --- packages/core/src/convertor/convertor.js | 27 +- packages/core/src/convertor/wxToAli.js | 6 +- packages/core/src/convertor/wxToSwan.js | 6 +- packages/core/src/convertor/wxToWeb.js | 6 +- packages/core/src/platform/createApp.ios.js | 4 +- packages/core/src/platform/createApp.js | 6 +- .../platform/patch/ali/getDefaultOptions.js | 193 ------ .../core/src/platform/patch/ali/lifecycle.js | 61 -- packages/core/src/platform/patch/index.js | 25 +- .../patch/react/getDefaultOptions.ios.js | 599 ------------------ .../platform/patch/react/getDefaultOptions.js | 1 - .../platform/patch/swan/getDefaultOptions.js | 34 - .../core/src/platform/patch/swan/lifecycle.js | 59 -- .../platform/patch/web/getDefaultOptions.js | 103 --- .../core/src/platform/patch/web/lifecycle.js | 51 -- .../platform/patch/wx/getDefaultOptions.js | 191 ------ .../core/src/platform/patch/wx/lifecycle.js | 71 --- 17 files changed, 21 insertions(+), 1422 deletions(-) delete mode 100644 packages/core/src/platform/patch/ali/getDefaultOptions.js delete mode 100644 packages/core/src/platform/patch/ali/lifecycle.js delete mode 100644 packages/core/src/platform/patch/react/getDefaultOptions.ios.js delete mode 100644 packages/core/src/platform/patch/react/getDefaultOptions.js delete mode 100644 packages/core/src/platform/patch/swan/getDefaultOptions.js delete mode 100644 packages/core/src/platform/patch/swan/lifecycle.js delete mode 100644 packages/core/src/platform/patch/web/getDefaultOptions.js delete mode 100644 packages/core/src/platform/patch/web/lifecycle.js delete mode 100644 packages/core/src/platform/patch/wx/getDefaultOptions.js delete mode 100644 packages/core/src/platform/patch/wx/lifecycle.js diff --git a/packages/core/src/convertor/convertor.js b/packages/core/src/convertor/convertor.js index 7571f505af..6139f4a194 100644 --- a/packages/core/src/convertor/convertor.js +++ b/packages/core/src/convertor/convertor.js @@ -1,7 +1,4 @@ -import * as wxLifecycle from '../platform/patch/wx/lifecycle' -import * as aliLifecycle from '../platform/patch/ali/lifecycle' -import * as webLifecycle from '../platform/patch/web/lifecycle' -import * as swanLifecycle from '../platform/patch/swan/lifecycle' +import { LIFECYCLE, lifecycleProxyMap, pageMode } from '../platform/patch/lifecycle/index' import { mergeLifecycle } from './mergeLifecycle' import { error } from '@mpxjs/utils' import wxToAliRule from './wxToAli' @@ -13,24 +10,6 @@ import wxToDdRule from './wxToDd' import wxToJdRule from './wxToJd' import wxToReactRule from './wxToReact' -// 根据当前环境获取的默认生命周期信息 -let lifecycleInfo -let pageMode - -if (__mpx_mode__ === 'web') { - lifecycleInfo = webLifecycle - pageMode = '' -} else if (__mpx_mode__ === 'ali') { - lifecycleInfo = aliLifecycle - pageMode = '' -} else if (__mpx_mode__ === 'swan') { - lifecycleInfo = swanLifecycle - pageMode = 'blend' -} else { - lifecycleInfo = wxLifecycle - pageMode = 'blend' -} - /** * 转换规则包含四点 * lifecycle [object] 生命周期 @@ -40,8 +19,8 @@ if (__mpx_mode__ === 'web') { * convert [function] 自定义转换函数, 接收一个options */ const defaultConvertRule = { - lifecycle: mergeLifecycle(lifecycleInfo.LIFECYCLE), - lifecycleProxyMap: lifecycleInfo.lifecycleProxyMap, + lifecycle: mergeLifecycle(LIFECYCLE), + lifecycleProxyMap: lifecycleProxyMap, pageMode, support: !!pageMode, convert: null diff --git a/packages/core/src/convertor/wxToAli.js b/packages/core/src/convertor/wxToAli.js index d47c372950..ffa0d2e697 100644 --- a/packages/core/src/convertor/wxToAli.js +++ b/packages/core/src/convertor/wxToAli.js @@ -1,5 +1,5 @@ -import * as wxLifecycle from '../platform/patch/wx/lifecycle' -import * as aliLifecycle from '../platform/patch/ali/lifecycle' +import * as wxLifecycle from '../platform/patch/lifecycle/index.wx' +import { LIFECYCLE } from '../platform/patch/lifecycle/index' import { mergeLifecycle } from './mergeLifecycle' import { error, hasOwn, isDev } from '@mpxjs/utils' import { implemented } from '../core/implement' @@ -38,7 +38,7 @@ function notSupportTip (options) { export default { lifecycle: mergeLifecycle(wxLifecycle.LIFECYCLE), - lifecycle2: mergeLifecycle(aliLifecycle.LIFECYCLE), + lifecycle2: mergeLifecycle(LIFECYCLE), pageMode: 'blend', support: false, lifecycleProxyMap: wxLifecycle.lifecycleProxyMap, diff --git a/packages/core/src/convertor/wxToSwan.js b/packages/core/src/convertor/wxToSwan.js index 6829ed296a..abfcbc8cda 100644 --- a/packages/core/src/convertor/wxToSwan.js +++ b/packages/core/src/convertor/wxToSwan.js @@ -1,8 +1,8 @@ import { error, isDev } from '@mpxjs/utils' import { implemented } from '../core/implement' import { mergeLifecycle } from './mergeLifecycle' -import * as wxLifecycle from '../platform/patch/wx/lifecycle' -import * as swanLifecycle from '../platform/patch/swan/lifecycle' +import * as wxLifecycle from '../platform/patch/lifecycle/index.wx' +import { LIFECYCLE } from '../platform/patch/lifecycle/index' const BEHAVIORS_MAP = { 'wx://form-field': 'swan://form-field', @@ -30,7 +30,7 @@ function notSupportTip (options) { export default { lifecycle: mergeLifecycle(wxLifecycle.LIFECYCLE), - lifecycle2: mergeLifecycle(swanLifecycle.LIFECYCLE), + lifecycle2: mergeLifecycle(LIFECYCLE), pageMode: 'blend', support: true, lifecycleProxyMap: wxLifecycle.lifecycleProxyMap, diff --git a/packages/core/src/convertor/wxToWeb.js b/packages/core/src/convertor/wxToWeb.js index cbd5af2cd8..bc56e6cb7d 100644 --- a/packages/core/src/convertor/wxToWeb.js +++ b/packages/core/src/convertor/wxToWeb.js @@ -1,5 +1,5 @@ -import * as wxLifecycle from '../platform/patch/wx/lifecycle' -import * as webLifecycle from '../platform/patch/web/lifecycle' +import * as wxLifecycle from '../platform/patch/lifecycle/index.wx' +import { LIFECYCLE } from '../platform/patch/lifecycle/index' import { mergeLifecycle } from './mergeLifecycle' import { isObject, @@ -32,7 +32,7 @@ function notSupportTip (options) { export default { lifecycle: mergeLifecycle(wxLifecycle.LIFECYCLE), - lifecycle2: mergeLifecycle(webLifecycle.LIFECYCLE), + lifecycle2: mergeLifecycle(LIFECYCLE), pageMode: 'blend', support: true, lifecycleProxyMap: wxLifecycle.lifecycleProxyMap, diff --git a/packages/core/src/platform/createApp.ios.js b/packages/core/src/platform/createApp.ios.js index db17c5efd8..0729a709fd 100644 --- a/packages/core/src/platform/createApp.ios.js +++ b/packages/core/src/platform/createApp.ios.js @@ -2,13 +2,13 @@ import transferOptions from '../core/transferOptions' import builtInKeysMap from './patch/builtInKeysMap' import { makeMap, spreadProp, parseUrlQuery, getFocusedNavigation } from '@mpxjs/utils' import { mergeLifecycle } from '../convertor/mergeLifecycle' -import * as wxLifecycle from '../platform/patch/wx/lifecycle' +import { LIFECYCLE } from '../platform/patch/lifecycle/index' import Mpx from '../index' import { createElement, memo, useRef, useEffect } from 'react' import * as ReactNative from 'react-native' import { ref } from '../observer/ref' -const appHooksMap = makeMap(mergeLifecycle(wxLifecycle.LIFECYCLE).app) +const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app) function getOrientation (window = ReactNative.Dimensions.get('window')) { return window.width > window.height ? 'landscape' : 'portrait' diff --git a/packages/core/src/platform/createApp.js b/packages/core/src/platform/createApp.js index 9c3e9ca17b..b22bab336d 100644 --- a/packages/core/src/platform/createApp.js +++ b/packages/core/src/platform/createApp.js @@ -3,11 +3,11 @@ import mergeOptions from '../core/mergeOptions' import builtInKeysMap from './patch/builtInKeysMap' import { makeMap, spreadProp, isBrowser } from '@mpxjs/utils' import { mergeLifecycle } from '../convertor/mergeLifecycle' -import * as webLifecycle from '../platform/patch/web/lifecycle' +import { LIFECYCLE } from '../platform/patch/lifecycle/index' import Mpx from '../index' import { initAppProvides } from './export/apiInject' -const webAppHooksMap = makeMap(mergeLifecycle(webLifecycle.LIFECYCLE).app) +const appHooksMap = makeMap(mergeLifecycle(LIFECYCLE).app) function filterOptions (options, appData) { const newOptions = {} @@ -15,7 +15,7 @@ function filterOptions (options, appData) { if (builtInKeysMap[key]) { return } - if (__mpx_mode__ === 'web' && !webAppHooksMap[key] && key !== 'provide') { + if (__mpx_mode__ === 'web' && !appHooksMap[key] && key !== 'provide') { appData[key] = options[key] } else { newOptions[key] = options[key] diff --git a/packages/core/src/platform/patch/ali/getDefaultOptions.js b/packages/core/src/platform/patch/ali/getDefaultOptions.js deleted file mode 100644 index 90810a590c..0000000000 --- a/packages/core/src/platform/patch/ali/getDefaultOptions.js +++ /dev/null @@ -1,193 +0,0 @@ -import MpxProxy from '../../../core/proxy' -import builtInKeysMap from '../builtInKeysMap' -import mergeOptions from '../../../core/mergeOptions' -import { error, diffAndCloneA, hasOwn, noop, wrapMethodsWithErrorHandling } from '@mpxjs/utils' - -function transformApiForProxy (context, currentInject) { - const rawSetData = context.setData.bind(context) - if (Object.getOwnPropertyDescriptor(context, 'setData').configurable) { - Object.defineProperty(context, 'setData', { - get () { - return function (data, callback) { - return context.__mpxProxy.forceUpdate(data, { sync: true }, callback) - } - }, - configurable: true - }) - } - Object.defineProperties(context, { - __getProps: { - get () { - return (options) => { - const props = {} - const validProps = Object.assign({}, options.properties, options.props) - if (context.props) { - Object.keys(context.props).forEach((key) => { - if (hasOwn(validProps, key)) { - props[key] = context.props[key] - } - }) - } - if (options.__nativeRender__) { - // 微信原生转支付宝时,首次将非函数props数据合入data中 - Object.assign(context.data, props) - } - return props - } - }, - configurable: false - }, - __render: { - get () { - return rawSetData - }, - configurable: false - } - }) - if (currentInject) { - Object.defineProperties(context, { - __injectedRender: { - get () { - return currentInject.render || noop - }, - configurable: false - } - }) - if (currentInject.getRefsData) { - Object.defineProperties(context, { - __getRefsData: { - get () { - return currentInject.getRefsData - }, - configurable: false - } - }) - } - if (currentInject.moduleId) { - Object.defineProperties(context, { - __moduleId: { - get () { - return currentInject.moduleId - }, - configurable: false - } - }) - } - if (currentInject.dynamic) { - Object.defineProperties(context, { - __dynamic: { - get () { - return currentInject.dynamic - }, - configurable: false - } - }) - } - } -} - -function filterOptions (options, type) { - const newOptions = {} - Object.keys(options).forEach(key => { - if (builtInKeysMap[key]) { - return - } - if (key === 'data' || key === 'initData') { - if (!hasOwn(newOptions, 'data')) { - newOptions.data = Object.assign({}, options.initData, options.data) - } - } else if (key === 'properties' || key === 'props') { - if (!hasOwn(newOptions, 'props')) { - newOptions.props = Object.assign({}, options.props, options.properties) - } - } else if (key === 'methods') { - const newMethods = wrapMethodsWithErrorHandling(options[key]) - if (type === 'page') { - // 构造器为Page时抽取所有methods方法到顶层 - Object.assign(newOptions, newMethods) - } else { - newOptions[key] = newMethods - } - } else if (key === 'behaviors') { - newOptions.mixins = options[key] - } else { - newOptions[key] = options[key] - } - }) - if (newOptions.relations) { - // ali relations 需要设置 options.relations = true - newOptions.options = newOptions.options || {} - newOptions.options.relations = true - } - return newOptions -} - -function initProxy (context, rawOptions, currentInject) { - if (!context.__mpxProxy) { - // 提供代理对象需要的api - transformApiForProxy(context, currentInject) - // 创建proxy对象 - context.__mpxProxy = new MpxProxy(rawOptions, context) - context.__mpxProxy.created() - } else if (context.__mpxProxy.isUnmounted()) { - context.__mpxProxy = new MpxProxy(rawOptions, context, true) - context.__mpxProxy.created() - } -} - -export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { - const hookNames = type === 'component' ? ['onInit', 'didMount', 'didUnmount'] : ['onLoad', 'onReady', 'onUnload'] - const rootMixins = [{ - [hookNames[0]] () { - if (rawOptions.__nativeRender__ && this.props) { - const validProps = Object.assign({}, rawOptions.props, rawOptions.properties) - Object.keys(this.props).forEach((key) => { - if (hasOwn(validProps, key)) { - this.data[key] = this.props[key] - } - }) - } - initProxy(this, rawOptions, currentInject) - }, - deriveDataFromProps (nextProps) { - if (this.__mpxProxy && this.__mpxProxy.isMounted() && nextProps && nextProps !== this.props) { - const validProps = Object.assign({}, rawOptions.props, rawOptions.properties) - if (rawOptions.__nativeRender__) { - const newData = {} - // 微信原生转换支付宝时,每次props更新将其设置进data模拟微信表现 - Object.keys(nextProps).forEach((key) => { - if (hasOwn(validProps, key)) { - const { diff, clone } = diffAndCloneA(nextProps[key], this.props[key]) - if (diff) newData[key] = clone - } - }) - this.setData(newData) - } else { - // 由于支付宝中props透传父级setData的值,此处发生变化的属性实例一定不同,只需浅比较即可确定发生变化的属性 - // 支付宝appx2.0版本后props传递发生变化,此处获取到的nextProps和this.props以及父组件setData的数据引用都不一致,进行了两次深克隆,此处this.props和nextProps的比对需要用deep diff - Object.keys(nextProps).forEach(key => { - if (hasOwn(validProps, key)) { - const { diff, clone } = diffAndCloneA(nextProps[key], this.props[key]) - // 由于支付宝中透传父级setData的值,此处进行深clone后赋值避免父级存储的miniRenderData部分数据在此处被响应化,在子组件对props赋值时触发父组件的render - if (diff) this[key] = clone - } - }) - this.__mpxProxy.propsUpdated() - } - } - }, - [hookNames[1]] () { - if (this.__mpxProxy) { - this.__mpxProxy.mounted() - } else { - error('请在支付宝开发工具的详情设置里面,启用component2编译。依赖基础库版本 >=1.14.0') - } - }, - [hookNames[2]] () { - if (this.__mpxProxy) this.__mpxProxy.unmounted() - } - }] - rawOptions.mixins = rawOptions.mixins ? rootMixins.concat(rawOptions.mixins) : rootMixins - rawOptions = mergeOptions(rawOptions, type, false) - return filterOptions(rawOptions, type) -} diff --git a/packages/core/src/platform/patch/ali/lifecycle.js b/packages/core/src/platform/patch/ali/lifecycle.js deleted file mode 100644 index 22f40bb1cf..0000000000 --- a/packages/core/src/platform/patch/ali/lifecycle.js +++ /dev/null @@ -1,61 +0,0 @@ -import { - CREATED, - UNMOUNTED, - MOUNTED, - ONHIDE, - ONSHOW, - ONLOAD, - UPDATED -} from '../../../core/innerLifecycle' - -const APP_HOOKS = [ - 'onLaunch', - 'onShow', - 'onHide', - 'onError', - 'onShareAppMessage', - 'onUnhandledRejection', - 'onPageNotFound' -] - -const PAGE_HOOKS = [ - 'onLoad', - 'onReady', - 'onShow', - 'onHide', - 'onUnload', - 'onShareAppMessage', - 'onTitleClick', - 'onOptionMenuClick', - 'onPullDownRefresh', - 'onTabItemTap', - 'onPageScroll', - 'onReachBottom' -] - -const COMPONENT_HOOKS = [ - 'onInit', - 'deriveDataFromProps', - 'didMount', - 'didUpdate', - 'didUnmount', - 'onError', - 'pageShow', - 'pageHide' -] - -export const lifecycleProxyMap = { - [CREATED]: ['onInit'], - [UPDATED]: ['didUpdate'], - [MOUNTED]: ['didMount', 'onReady'], - [UNMOUNTED]: ['didUnmount', 'onUnload'], - [ONSHOW]: ['pageShow', 'onShow'], - [ONHIDE]: ['pageHide', 'onHide'], - [ONLOAD]: ['onLoad'] -} - -export const LIFECYCLE = { - APP_HOOKS, - PAGE_HOOKS, - COMPONENT_HOOKS -} diff --git a/packages/core/src/platform/patch/index.js b/packages/core/src/platform/patch/index.js index 11f006e2bb..17f1c52870 100644 --- a/packages/core/src/platform/patch/index.js +++ b/packages/core/src/platform/patch/index.js @@ -1,18 +1,14 @@ import transferOptions from '../../core/transferOptions' import getBuiltInMixins from '../builtInMixins/index' -import { getDefaultOptions as getWxDefaultOptions } from './wx/getDefaultOptions' -import { getDefaultOptions as getAliDefaultOptions } from './ali/getDefaultOptions' -import { getDefaultOptions as getSwanDefaultOptions } from './swan/getDefaultOptions' -import { getDefaultOptions as getWebDefaultOptions } from './web/getDefaultOptions' -import { getDefaultOptions as getReactDefaultOptions } from './react/getDefaultOptions' -import { error } from '@mpxjs/utils' +import { getDefaultOptions } from './getDefaultOptions' +import { error, isReact, isWeb } from '@mpxjs/utils' export default function createFactory (type) { return (options = {}, { isNative, customCtor, customCtorType } = {}) => { options.__nativeRender__ = !!isNative options.__type__ = type let ctor - if (__mpx_mode__ !== 'web' && __mpx_mode__ !== 'ios' && __mpx_mode__ !== 'android') { + if (!isWeb && !isReact) { if (customCtor) { ctor = customCtor customCtorType = customCtorType || type @@ -39,19 +35,6 @@ export default function createFactory (type) { } } - let getDefaultOptions - if (__mpx_mode__ === 'ios' || __mpx_mode__ === 'android') { - getDefaultOptions = getReactDefaultOptions - } else if (__mpx_mode__ === 'web') { - getDefaultOptions = getWebDefaultOptions - } else if (__mpx_mode__ === 'ali') { - getDefaultOptions = getAliDefaultOptions - } else if (__mpx_mode__ === 'swan') { - getDefaultOptions = getSwanDefaultOptions - } else { - getDefaultOptions = getWxDefaultOptions - } - const { setup } = options const { rawOptions, currentInject } = transferOptions(options, type) rawOptions.setup = setup @@ -60,7 +43,7 @@ export default function createFactory (type) { // 将合并后的用户定义的rawOptions传入获取当前应该注入的内建mixins rawOptions.mixins = getBuiltInMixins({ type, rawOptions, currentInject }) const defaultOptions = getDefaultOptions({ type, rawOptions, currentInject }) - if (__mpx_mode__ === 'web' || __mpx_mode__ === 'ios' || __mpx_mode__ === 'android') { + if (isWeb || isReact) { global.__mpxOptionsMap = global.__mpxOptionsMap || {} global.__mpxOptionsMap[currentInject.moduleId] = defaultOptions } else if (ctor) { diff --git a/packages/core/src/platform/patch/react/getDefaultOptions.ios.js b/packages/core/src/platform/patch/react/getDefaultOptions.ios.js deleted file mode 100644 index 98a76714e4..0000000000 --- a/packages/core/src/platform/patch/react/getDefaultOptions.ios.js +++ /dev/null @@ -1,599 +0,0 @@ -import { useEffect, useLayoutEffect, useSyncExternalStore, useRef, useMemo, useState, useCallback, createElement, memo, forwardRef, useImperativeHandle, useContext, Fragment, cloneElement } from 'react' -import * as ReactNative from 'react-native' -import { ReactiveEffect } from '../../../observer/effect' -import { watch } from '../../../observer/watch' -import { reactive, set, del } from '../../../observer/reactive' -import { hasOwn, isFunction, noop, isObject, isArray, getByPath, collectDataset, hump2dash, wrapMethodsWithErrorHandling } from '@mpxjs/utils' -import MpxProxy from '../../../core/proxy' -import { BEFOREUPDATE, ONLOAD, UPDATED, ONSHOW, ONHIDE, ONRESIZE, REACTHOOKSEXEC } from '../../../core/innerLifecycle' -import mergeOptions from '../../../core/mergeOptions' -import { queueJob, hasPendingJob } from '../../../observer/scheduler' -import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy' -import { IntersectionObserverContext, RouteContext, KeyboardAvoidContext } from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/context' - -function getSystemInfo () { - const window = ReactNative.Dimensions.get('window') - const screen = ReactNative.Dimensions.get('screen') - return { - deviceOrientation: window.width > window.height ? 'landscape' : 'portrait', - size: { - screenWidth: screen.width, - screenHeight: screen.height, - windowWidth: window.width, - windowHeight: window.height - } - } -} - -function createEffect (proxy, components) { - const update = proxy.update = () => { - // react update props in child render(async), do not need exec pre render - // if (proxy.propsUpdatedFlag) { - // proxy.updatePreRender() - // } - if (proxy.isMounted()) { - proxy.callHook(BEFOREUPDATE) - proxy.pendingUpdatedFlag = true - } - proxy.stateVersion = Symbol() - proxy.onStoreChange && proxy.onStoreChange() - } - update.id = proxy.uid - const getComponent = (tagName) => { - if (!tagName) return null - if (tagName === 'block') return Fragment - return components[tagName] || getByPath(ReactNative, tagName) - } - const innerCreateElement = (type, ...rest) => { - if (!type) return null - return createElement(type, ...rest) - } - - proxy.effect = new ReactiveEffect(() => { - // reset instance - proxy.target.__resetInstance() - return proxy.target.__injectedRender(innerCreateElement, getComponent) - }, () => queueJob(update), proxy.scope) - // render effect允许自触发 - proxy.toggleRecurse(true) -} - -function getRootProps (props) { - const rootProps = {} - for (const key in props) { - if (hasOwn(props, key)) { - const match = /^(bind|catch|capture-bind|capture-catch|style|enable-var):?(.*?)(?:\.(.*))?$/.exec(key) - if (match) { - rootProps[key] = props[key] - } - } - } - return rootProps -} - -const instanceProto = { - setData (data, callback) { - return this.__mpxProxy.forceUpdate(data, { sync: true }, callback) - }, - triggerEvent (eventName, eventDetail) { - const props = this.__props - const handler = props && (props['bind' + eventName] || props['catch' + eventName] || props['capture-bind' + eventName] || props['capture-catch' + eventName]) - if (handler && typeof handler === 'function') { - const timeStamp = +new Date() - const dataset = collectDataset(props) - const id = props.id || '' - const eventObj = { - type: eventName, - timeStamp, - target: { - id, - dataset, - targetDataset: dataset - }, - currentTarget: { - id, - dataset - }, - detail: eventDetail - } - handler.call(this, eventObj) - } - }, - getPageId () { - return this.__pageId - }, - selectComponent (selector) { - return this.__selectRef(selector, 'component') - }, - selectAllComponents (selector) { - return this.__selectRef(selector, 'component', true) - }, - createSelectorQuery () { - return createSelectorQuery().in(this) - }, - createIntersectionObserver (opt) { - return createIntersectionObserver(this, opt, this.__intersectionCtx) - }, - __resetInstance () { - this.__refs = {} - this.__dispatchedSlotSet = new WeakSet() - }, - __iter (val, fn) { - let i, l, keys, key - const result = [] - if (isArray(val) || typeof val === 'string') { - for (i = 0, l = val.length; i < l; i++) { - result.push(fn.call(this, val[i], i)) - } - } else if (typeof val === 'number') { - for (i = 0; i < val; i++) { - result.push(fn.call(this, i + 1, i)) - } - } else if (isObject(val)) { - keys = Object.keys(val) - for (i = 0, l = keys.length; i < l; i++) { - key = keys[i] - result.push(fn.call(this, val[key], key, i)) - } - } - return result - }, - __getProps () { - const props = this.__props - const validProps = this.__validProps - const propsData = {} - Object.keys(validProps).forEach((key) => { - if (hasOwn(props, key)) { - propsData[key] = props[key] - } else { - const altKey = hump2dash(key) - if (hasOwn(props, altKey)) { - propsData[key] = props[altKey] - } else { - let field = validProps[key] - if (isFunction(field) || field === null) { - field = { - type: field - } - } - // 处理props默认值 - propsData[key] = field.value - } - } - }) - return propsData - }, - __getSlot (name, slot) { - const { children } = this.__props - if (children) { - let result = [] - if (isArray(children) && !hasOwn(children, '__slot')) { - children.forEach(child => { - if (hasOwn(child, '__slot')) { - if (child.__slot === name) result.push(...child) - } else if (child?.props?.slot === name) { - result.push(child) - } - }) - } else { - if (hasOwn(children, '__slot')) { - if (children.__slot === name) result.push(...children) - } else if (children?.props?.slot === name) { - result.push(children) - } - } - result = result.filter(item => { - if (!isObject(item) || this.__dispatchedSlotSet.has(item)) return false - this.__dispatchedSlotSet.add(item) - return true - }) - if (!result.length) return null - result.__slot = slot - return result - } - return null - } -} - -function createInstance ({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx }) { - const instance = Object.create(instanceProto, { - dataset: { - get () { - const props = propsRef.current - return collectDataset(props) - }, - enumerable: true - }, - id: { - get () { - const props = propsRef.current - return props.id - }, - enumerable: true - }, - __props: { - get () { - return propsRef.current - }, - enumerable: false - }, - __pageId: { - get () { - return pageId - }, - enumerable: false - }, - __intersectionCtx: { - get () { - return intersectionCtx - }, - enumerable: false - }, - __validProps: { - get () { - return validProps - }, - enumerable: false - }, - __injectedRender: { - get () { - return currentInject.render || noop - }, - enumerable: false - }, - __getRefsData: { - get () { - return currentInject.getRefsData || noop - }, - enumerable: false - } - }) - - // bind this & assign methods - if (rawOptions.methods) { - Object.entries(rawOptions.methods).forEach(([key, method]) => { - instance[key] = method.bind(instance) - }) - } - - if (type === 'page') { - const props = propsRef.current - instance.route = props.route.name - global.__mpxPagesMap[props.route.key] = [instance, props.navigation] - } - - const proxy = instance.__mpxProxy = new MpxProxy(rawOptions, instance) - proxy.created() - - Object.assign(proxy, { - onStoreChange: null, - stateVersion: Symbol(), - subscribe: (onStoreChange) => { - if (!proxy.effect) { - createEffect(proxy, components) - proxy.stateVersion = Symbol() - } - proxy.onStoreChange = onStoreChange - return () => { - proxy.effect && proxy.effect.stop() - proxy.effect = null - proxy.onStoreChange = null - } - }, - getSnapshot: () => { - return proxy.stateVersion - } - }) - // react数据响应组件更新管理器 - if (!proxy.effect) { - createEffect(proxy, components) - } - - return instance -} - -function hasPageHook (mpxProxy, hookNames) { - const options = mpxProxy.options - const type = options.__type__ - return hookNames.some(h => { - if (mpxProxy.hasHook(h)) { - return true - } - if (type === 'page') { - return isFunction(options.methods && options.methods[h]) - } else if (type === 'component') { - return options.pageLifetimes && isFunction(options.pageLifetimes[h]) - } - return false - }) -} - -const triggerPageStatusHook = (mpxProxy, event) => { - mpxProxy.callHook(event === 'show' ? ONSHOW : ONHIDE) - const pageLifetimes = mpxProxy.options.pageLifetimes - if (pageLifetimes) { - const instance = mpxProxy.target - isFunction(pageLifetimes[event]) && pageLifetimes[event].call(instance) - } -} - -const triggerResizeEvent = (mpxProxy) => { - const type = mpxProxy.options.__type__ - const systemInfo = getSystemInfo() - const target = mpxProxy.target - mpxProxy.callHook(ONRESIZE, [systemInfo]) - if (type === 'page') { - target.onResize && target.onResize(systemInfo) - } else { - const pageLifetimes = mpxProxy.options.pageLifetimes - pageLifetimes && isFunction(pageLifetimes.resize) && pageLifetimes.resize.call(target, systemInfo) - } -} - -function usePageEffect (mpxProxy, pageId) { - useEffect(() => { - let unWatch - const hasShowHook = hasPageHook(mpxProxy, [ONSHOW, 'show']) - const hasHideHook = hasPageHook(mpxProxy, [ONHIDE, 'hide']) - const hasResizeHook = hasPageHook(mpxProxy, [ONRESIZE, 'resize']) - if (hasShowHook || hasHideHook || hasResizeHook) { - if (hasOwn(pageStatusContext, pageId)) { - unWatch = watch(() => pageStatusContext[pageId], (newVal) => { - if (newVal === 'show' || newVal === 'hide') { - triggerPageStatusHook(mpxProxy, newVal) - } else if (/^resize/.test(newVal)) { - triggerResizeEvent(mpxProxy) - } - }) - } - } - return () => { - unWatch && unWatch() - } - }, []) -} - -const pageStatusContext = reactive({}) -let pageId = 0 - -function usePageStatus (navigation, pageId) { - let isFocused = true - set(pageStatusContext, pageId, '') - useEffect(() => { - const focusSubscription = navigation.addListener('focus', () => { - pageStatusContext[pageId] = 'show' - isFocused = true - }) - const blurSubscription = navigation.addListener('blur', () => { - pageStatusContext[pageId] = 'hide' - isFocused = false - }) - const unWatchAppFocusedState = watch(global.__mpxAppFocusedState, (value) => { - if (isFocused) { - pageStatusContext[pageId] = value - } - }) - - return () => { - focusSubscription() - blurSubscription() - unWatchAppFocusedState() - del(pageStatusContext, pageId) - } - }, [navigation]) -} - -export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { - rawOptions = mergeOptions(rawOptions, type, false) - const components = Object.assign({}, rawOptions.components, currentInject.getComponents()) - const validProps = Object.assign({}, rawOptions.props, rawOptions.properties) - if (rawOptions.methods) rawOptions.methods = wrapMethodsWithErrorHandling(rawOptions.methods) - const defaultOptions = memo(forwardRef((props, ref) => { - const instanceRef = useRef(null) - const propsRef = useRef(null) - const intersectionCtx = useContext(IntersectionObserverContext) - const pageId = useContext(RouteContext) - propsRef.current = props - let isFirst = false - if (!instanceRef.current) { - isFirst = true - instanceRef.current = createInstance({ propsRef, type, rawOptions, currentInject, validProps, components, pageId, intersectionCtx }) - } - const instance = instanceRef.current - useImperativeHandle(ref, () => { - return instance - }) - - const proxy = instance.__mpxProxy - - let hooksResult = proxy.callHook(REACTHOOKSEXEC, [props]) - if (isObject(hooksResult)) { - hooksResult = wrapMethodsWithErrorHandling(hooksResult, proxy) - if (isFirst) { - const onConflict = proxy.createProxyConflictHandler('react hooks result') - Object.keys(hooksResult).forEach((key) => { - if (key in proxy.target) { - onConflict(key) - } - proxy.target[key] = hooksResult[key] - }) - } else { - Object.assign(proxy.target, hooksResult) - } - } - - if (!isFirst) { - // 处理props更新 - Object.keys(validProps).forEach((key) => { - if (hasOwn(props, key)) { - instance[key] = props[key] - } else { - const altKey = hump2dash(key) - if (hasOwn(props, altKey)) { - instance[key] = props[altKey] - } - } - }) - } - - useEffect(() => { - if (proxy.pendingUpdatedFlag) { - proxy.pendingUpdatedFlag = false - proxy.callHook(UPDATED) - } - }) - - usePageEffect(proxy, pageId) - - useEffect(() => { - if (type === 'page') { - if (!global.__mpxAppLaunched && global.__mpxAppOnLaunch) { - global.__mpxAppOnLaunch(props.navigation) - } - proxy.callHook(ONLOAD, [props.route.params || {}]) - } - proxy.mounted() - return () => { - proxy.unmounted() - proxy.target.__resetInstance() - if (type === 'page') { - delete global.__mpxPagesMap[props.route.key] - } - } - }, []) - - useSyncExternalStore(proxy.subscribe, proxy.getSnapshot) - - if ((rawOptions.options?.disableMemo)) { - proxy.memoVersion = Symbol() - } - - const finalMemoVersion = useMemo(() => { - if (!hasPendingJob(proxy.update)) { - proxy.finalMemoVersion = Symbol() - } - return proxy.finalMemoVersion - }, [proxy.stateVersion, proxy.memoVersion]) - - const root = useMemo(() => proxy.effect.run(), [finalMemoVersion]) - if (root && root.props.ishost) { - const rootProps = getRootProps(props) - rootProps.style = Object.assign({}, root.props.style, rootProps.style) - // update root props - return cloneElement(root, rootProps) - } - return root - })) - - if (rawOptions.options?.isCustomText) { - defaultOptions.isCustomText = true - } - - if (type === 'page') { - const { Provider, useSafeAreaInsets, GestureHandlerRootView } = global.__navigationHelper - const pageConfig = Object.assign({}, global.__mpxPageConfig, currentInject.pageConfig) - const Page = ({ navigation, route }) => { - const [enabled, setEnabled] = useState(true) - const currentPageId = useMemo(() => ++pageId, []) - const intersectionObservers = useRef({}) - usePageStatus(navigation, currentPageId) - - useLayoutEffect(() => { - const isCustom = pageConfig.navigationStyle === 'custom' - navigation.setOptions({ - headerShown: !isCustom, - title: pageConfig.navigationBarTitleText || '', - headerStyle: { - backgroundColor: pageConfig.navigationBarBackgroundColor || '#000000' - }, - headerTintColor: pageConfig.navigationBarTextStyle || 'white' - }) - if (__mpx_mode__ === 'android') { - ReactNative.StatusBar.setBarStyle(pageConfig.barStyle || 'dark-content') - ReactNative.StatusBar.setTranslucent(isCustom) // 控制statusbar是否占位 - const color = isCustom ? 'transparent' : pageConfig.statusBarColor - color && ReactNative.StatusBar.setBackgroundColor(color) - } - }, []) - - const rootRef = useRef(null) - const onLayout = useCallback(() => { - rootRef.current?.measureInWindow((x, y, width, height) => { - navigation.layout = { x, y, width, height } - }) - }, []) - - const withKeyboardAvoidingView = (element) => { - if (__mpx_mode__ === 'ios') { - return createElement(KeyboardAvoidContext.Provider, - { - value: setEnabled - }, - createElement(ReactNative.KeyboardAvoidingView, - { - style: { - flex: 1 - }, - contentContainerStyle: { - flex: 1 - }, - behavior: 'position', - enabled - }, - element - ) - ) - } - return element - } - - navigation.insets = useSafeAreaInsets() - - return createElement(GestureHandlerRootView, - { - style: { - flex: 1 - } - }, - withKeyboardAvoidingView( - createElement(ReactNative.View, - { - style: { - flex: 1, - backgroundColor: pageConfig.backgroundColor || '#ffffff' - }, - ref: rootRef, - onLayout, - onTouchStart: () => { - ReactNative.Keyboard.isVisible() && ReactNative.Keyboard.dismiss() - } - }, - createElement(RouteContext.Provider, - { - value: currentPageId - }, - createElement(IntersectionObserverContext.Provider, - { - value: intersectionObservers.current - }, - createElement(Provider, - null, - createElement(defaultOptions, - { - navigation, - route, - id: currentPageId - } - ) - ) - ) - ) - ) - ) - ) - // todo custom portal host for active route - } - return Page - } - return defaultOptions -} diff --git a/packages/core/src/platform/patch/react/getDefaultOptions.js b/packages/core/src/platform/patch/react/getDefaultOptions.js deleted file mode 100644 index 15883ae643..0000000000 --- a/packages/core/src/platform/patch/react/getDefaultOptions.js +++ /dev/null @@ -1 +0,0 @@ -export function getDefaultOptions () {} diff --git a/packages/core/src/platform/patch/swan/getDefaultOptions.js b/packages/core/src/platform/patch/swan/getDefaultOptions.js deleted file mode 100644 index 6269d298ad..0000000000 --- a/packages/core/src/platform/patch/swan/getDefaultOptions.js +++ /dev/null @@ -1,34 +0,0 @@ -import mergeOptions from '../../../core/mergeOptions' -import { initProxy, filterOptions } from '../wx/getDefaultOptions' - -export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { - let hookNames = ['attached', 'ready', 'detached'] - // 当用户传入page作为构造器构造页面时,修改所有关键hooks - if (rawOptions.__pageCtor__) { - hookNames = ['onLoad', 'onReady', 'onUnload'] - } - - const rootMixin = { - [hookNames[0]] () { - initProxy(this, rawOptions, currentInject) - }, - [hookNames[1]] () { - if (this.__mpxProxy) this.__mpxProxy.mounted() - }, - [hookNames[2]] () { - if (this.__mpxProxy) this.__mpxProxy.unmounted() - } - } - - // 如构造页面,优先使用onInit进行初始化 - if (type === 'page') { - rootMixin.onInit = function (...params) { - initProxy(this, rawOptions, currentInject, params) - } - } - - const rootMixins = [rootMixin] - rawOptions.mixins = rawOptions.mixins ? rootMixins.concat(rawOptions.mixins) : rootMixins - rawOptions = mergeOptions(rawOptions, type, false) - return filterOptions(rawOptions) -} diff --git a/packages/core/src/platform/patch/swan/lifecycle.js b/packages/core/src/platform/patch/swan/lifecycle.js deleted file mode 100644 index eb7f3bffd5..0000000000 --- a/packages/core/src/platform/patch/swan/lifecycle.js +++ /dev/null @@ -1,59 +0,0 @@ -import { - CREATED, - UNMOUNTED, - MOUNTED, - ONSHOW, - ONHIDE, - ONLOAD, - ONRESIZE -} from '../../../core/innerLifecycle' - -const APP_HOOKS = [ - 'onLogin', - 'onLaunch', - 'onShow', - 'onHide', - 'onError', - 'onPageNotFound' -] - -const PAGE_HOOKS = [ - 'onInit', - 'onLoad', - 'onReady', - 'onShow', - 'onHide', - 'onUnload', - 'onPullDownRefresh', - 'onReachBottom', - 'onPageScroll', - 'onShareAppMessage', - 'onTabItemTap', - 'onURLQueryChange', - 'onResize' -] - -const COMPONENT_HOOKS = [ - 'created', - 'attached', - 'ready', - 'detached', - 'pageShow', - 'pageHide' -] - -export const lifecycleProxyMap = { - [CREATED]: ['onInit', 'created', 'attached'], - [MOUNTED]: ['ready', 'onReady'], - [UNMOUNTED]: ['detached', 'onUnload'], - [ONSHOW]: ['pageShow', 'onShow'], - [ONHIDE]: ['pageHide', 'onHide'], - [ONLOAD]: ['onLoad'], - [ONRESIZE]: ['onResize'] -} - -export const LIFECYCLE = { - APP_HOOKS, - PAGE_HOOKS, - COMPONENT_HOOKS -} diff --git a/packages/core/src/platform/patch/web/getDefaultOptions.js b/packages/core/src/platform/patch/web/getDefaultOptions.js deleted file mode 100644 index c2b874fcba..0000000000 --- a/packages/core/src/platform/patch/web/getDefaultOptions.js +++ /dev/null @@ -1,103 +0,0 @@ -import builtInKeysMap from '../builtInKeysMap' -import mergeOptions from '../../../core/mergeOptions' -import { diffAndCloneA, hasOwn, wrapMethodsWithErrorHandling } from '@mpxjs/utils' -import { getCurrentInstance as getCurrentVueInstance } from '../../export/index' -import MpxProxy, { setCurrentInstance, unsetCurrentInstance } from '../../../core/proxy' -import { - BEFORECREATE, - BEFOREUPDATE, - UPDATED, - BEFOREUNMOUNT, - UNMOUNTED, - SERVERPREFETCH -} from '../../../core/innerLifecycle' - -function filterOptions (options) { - const newOptions = {} - Object.keys(options).forEach(key => { - if (builtInKeysMap[key]) { - return - } - if (key === 'data' || key === 'dataFn') { - if (!hasOwn(newOptions, 'data')) { - newOptions.data = function mergeFn () { - return Object.assign( - diffAndCloneA(options.data || {}).clone, - options.dataFn && options.dataFn.call(this) - ) - } - } - } else if (key === 'methods') { - newOptions[key] = wrapMethodsWithErrorHandling(options[key]) - } else { - newOptions[key] = options[key] - } - }) - return newOptions -} - -function initProxy (context, rawOptions) { - if (!context.__mpxProxy) { - context.__mpxProxy = new MpxProxy(rawOptions, context) - context.__mpxProxy.callHook(BEFORECREATE) - } else if (context.__mpxProxy.isUnmounted()) { - context.__mpxProxy = new MpxProxy(rawOptions, context, true) - context.__mpxProxy.callHook(BEFORECREATE) - } -} - -export function getDefaultOptions ({ type, rawOptions = {} }) { - const rawSetup = rawOptions.setup - if (rawSetup) { - rawOptions.setup = (props) => { - const instance = getCurrentVueInstance().proxy - initProxy(instance, rawOptions) - setCurrentInstance(instance.__mpxProxy) - const newContext = { - triggerEvent: instance.triggerEvent.bind(instance), - refs: instance.$refs, - forceUpdate: instance.$forceUpdate.bind(instance), - selectComponent: instance.selectComponent.bind(instance), - selectAllComponents: instance.selectAllComponents.bind(instance), - createSelectorQuery: instance.createSelectorQuery.bind(instance), - createIntersectionObserver: instance.createIntersectionObserver.bind(instance) - } - const setupRes = rawSetup(props, newContext) - unsetCurrentInstance(instance.__mpxProxy) - return wrapMethodsWithErrorHandling(setupRes, instance.__mpxProxy) - } - } - const rootMixins = [{ - beforeCreate () { - initProxy(this, rawOptions) - }, - created () { - if (this.__mpxProxy) this.__mpxProxy.created() - }, - mounted () { - if (this.__mpxProxy) this.__mpxProxy.mounted() - }, - beforeUpdate () { - if (this.__mpxProxy) this.__mpxProxy.callHook(BEFOREUPDATE) - }, - updated () { - if (this.__mpxProxy) this.__mpxProxy.callHook(UPDATED) - }, - beforeDestroy () { - if (this.__mpxProxy) this.__mpxProxy.callHook(BEFOREUNMOUNT) - }, - destroyed () { - if (this.__mpxProxy) { - this.__mpxProxy.state = UNMOUNTED - this.__mpxProxy.callHook(UNMOUNTED) - } - }, - serverPrefetch () { - if (this.__mpxProxy) return this.__mpxProxy.callHook(SERVERPREFETCH) - } - }] - // 为了在builtMixin中可以使用某些rootMixin实现的特性(如数据响应等),此处builtInMixin在rootMixin之后执行,但是当builtInMixin使用存在对应内建生命周期的目标平台声明周期写法时,可能会出现用户生命周期比builtInMixin中的生命周期先执行的情况,为了避免这种情况发生,builtInMixin应该尽可能使用内建生命周期来编写 - rawOptions.mixins = rawOptions.mixins ? rootMixins.concat(rawOptions.mixins) : rootMixins - rawOptions = mergeOptions(rawOptions, type, false) - return filterOptions(rawOptions) -} diff --git a/packages/core/src/platform/patch/web/lifecycle.js b/packages/core/src/platform/patch/web/lifecycle.js deleted file mode 100644 index 08eeb777eb..0000000000 --- a/packages/core/src/platform/patch/web/lifecycle.js +++ /dev/null @@ -1,51 +0,0 @@ -const COMPONENT_HOOKS = [ - 'beforeCreate', - 'created', - 'beforeMount', - 'mounted', - 'beforeUpdate', - 'updated', - 'activated', - 'deactivated', - 'beforeDestroy', - 'destroyed', - 'errorCaptured', - 'serverPrefetch' -] - -const PAGE_HOOKS = [ - ...COMPONENT_HOOKS, - 'onLoad', - 'onReady', - 'onShow', - 'onHide', - 'onUnload', - 'onPullDownRefresh', - 'onReachBottom', - 'onPageScroll', - 'onAddToFavorites', - 'onShareAppMessage', - 'onShareTimeline', - 'onResize', - 'onTabItemTap', - 'onSaveExitState' -] - -const APP_HOOKS = [ - ...COMPONENT_HOOKS, - 'onLaunch', - 'onShow', - 'onHide', - 'onError', - 'onPageNotFound', - 'onUnhandledRejection', - 'onThemeChange', - 'onSSRAppCreated', - 'onAppInit' -] - -export const LIFECYCLE = { - APP_HOOKS, - PAGE_HOOKS, - COMPONENT_HOOKS -} diff --git a/packages/core/src/platform/patch/wx/getDefaultOptions.js b/packages/core/src/platform/patch/wx/getDefaultOptions.js deleted file mode 100644 index 5c7d250dee..0000000000 --- a/packages/core/src/platform/patch/wx/getDefaultOptions.js +++ /dev/null @@ -1,191 +0,0 @@ -import { hasOwn, noop, isFunction, wrapMethodsWithErrorHandling } from '@mpxjs/utils' -import MpxProxy from '../../../core/proxy' -import builtInKeysMap from '../builtInKeysMap' -import mergeOptions from '../../../core/mergeOptions' - -function transformProperties (properties) { - if (!properties) { - return {} - } - const newProps = {} - Object.keys(properties).forEach(key => { - let rawFiled = properties[key] - let newFiled = null - if (rawFiled === null) { - rawFiled = { - type: null - } - } - if (isFunction(rawFiled)) { - newFiled = { - type: rawFiled - } - } else { - newFiled = Object.assign({}, rawFiled) - } - const rawObserver = rawFiled?.observer - newFiled.observer = function (value, oldValue) { - if (this.__mpxProxy) { - this[key] = value - this.__mpxProxy.propsUpdated() - } - rawObserver && rawObserver.call(this, value, oldValue) - } - newProps[key] = newFiled - }) - return newProps -} - -function transformApiForProxy (context, currentInject) { - const rawSetData = context.setData - Object.defineProperties(context, { - setData: { - get () { - return function (data, callback) { - return context.__mpxProxy.forceUpdate(data, { sync: true }, callback) - } - }, - configurable: true - }, - __getProps: { - get () { - return (options) => { - const props = {} - const validProps = Object.assign({}, options.properties, options.props) - Object.keys(context.data).forEach((key) => { - if (hasOwn(validProps, key)) { - props[key] = context.data[key] - } - }) - return props - } - }, - configurable: false - }, - __render: { - get () { - return rawSetData - }, - configurable: false - } - }) - - // // 抹平处理tt不支持驼峰事件名的问题 - // if (__mpx_mode__ === 'tt') { - // const rawTriggerEvent = context.triggerEvent - // Object.defineProperty(context, 'triggerEvent', { - // get () { - // return function (eventName, eventDetail) { - // return rawTriggerEvent.call(this, eventName.toLowerCase(), eventDetail) - // } - // }, - // configurable: true - // }) - // } - - // 绑定注入的render - if (currentInject) { - Object.defineProperties(context, { - __injectedRender: { - get () { - return currentInject.render || noop - }, - configurable: false - } - }) - if (currentInject.getRefsData) { - Object.defineProperties(context, { - __getRefsData: { - get () { - return currentInject.getRefsData - }, - configurable: false - } - }) - } - if (currentInject.moduleId) { - Object.defineProperties(context, { - __moduleId: { - get () { - return currentInject.moduleId - }, - configurable: false - } - }) - } - if (currentInject.dynamic) { - Object.defineProperties(context, { - __dynamic: { - get () { - return currentInject.dynamic - }, - configurable: false - } - }) - } - } -} - -export function filterOptions (options) { - const newOptions = {} - Object.keys(options).forEach(key => { - if (builtInKeysMap[key]) { - return - } - if (key === 'data' || key === 'initData') { - if (!hasOwn(newOptions, 'data')) { - newOptions.data = Object.assign({}, options.initData, options.data) - } - } else if (key === 'properties' || key === 'props') { - if (!hasOwn(newOptions, 'properties')) { - newOptions.properties = transformProperties(Object.assign({}, options.props, options.properties)) - } - } else if (key === 'methods') { - const newMethods = wrapMethodsWithErrorHandling(options[key]) - if (options.__pageCtor__) { - // 构造器为Page时抽取所有methods方法到顶层 - Object.assign(newOptions, newMethods) - } else { - newOptions[key] = newMethods - } - } else { - newOptions[key] = options[key] - } - }) - return newOptions -} - -export function initProxy (context, rawOptions, currentInject) { - if (!context.__mpxProxy) { - // 提供代理对象需要的api - transformApiForProxy(context, currentInject) - // 创建proxy对象 - context.__mpxProxy = new MpxProxy(rawOptions, context) - context.__mpxProxy.created() - } else if (context.__mpxProxy.isUnmounted()) { - context.__mpxProxy = new MpxProxy(rawOptions, context, true) - context.__mpxProxy.created() - } -} - -export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { - let hookNames = ['attached', 'ready', 'detached'] - // 当用户传入page作为构造器构造页面时,修改所有关键hooks - if (rawOptions.__pageCtor__) { - hookNames = ['onLoad', 'onReady', 'onUnload'] - } - const rootMixins = [{ - [hookNames[0]] () { - initProxy(this, rawOptions, currentInject) - }, - [hookNames[1]] () { - if (this.__mpxProxy) this.__mpxProxy.mounted() - }, - [hookNames[2]] () { - if (this.__mpxProxy) this.__mpxProxy.unmounted() - } - }] - rawOptions.mixins = rawOptions.mixins ? rootMixins.concat(rawOptions.mixins) : rootMixins - rawOptions = mergeOptions(rawOptions, type, false) - return filterOptions(rawOptions) -} diff --git a/packages/core/src/platform/patch/wx/lifecycle.js b/packages/core/src/platform/patch/wx/lifecycle.js deleted file mode 100644 index 662cfeb16f..0000000000 --- a/packages/core/src/platform/patch/wx/lifecycle.js +++ /dev/null @@ -1,71 +0,0 @@ -import { - CREATED, - UNMOUNTED, - MOUNTED, - ONSHOW, - ONHIDE, - ONLOAD, - ONRESIZE, - SERVERPREFETCH, - REACTHOOKSEXEC -} from '../../../core/innerLifecycle' - -const APP_HOOKS = [ - 'onLaunch', - 'onShow', - 'onHide', - 'onError', - 'onPageNotFound', - 'onUnhandledRejection', - 'onThemeChange', - 'onSSRAppCreated', - 'onAppInit' -] - -const PAGE_HOOKS = [ - 'onLoad', - 'onReady', - 'onShow', - 'onHide', - 'onUnload', - 'onPullDownRefresh', - 'onReachBottom', - 'onPageScroll', - 'onAddToFavorites', - 'onShareAppMessage', - 'onShareTimeline', - 'onResize', - 'onTabItemTap', - 'onSaveExitState' -] - -const COMPONENT_HOOKS = [ - 'created', - 'attached', - 'ready', - 'moved', - 'detached', - 'pageShow', - 'pageHide', - 'serverPrefetch', - 'reactHooksExec' -] - -export const lifecycleProxyMap = { - // 类微信平台中onLoad不能代理到CREATED上,否则Component构造页面时无法获取页面参数 - [CREATED]: ['created', 'attached'], - [MOUNTED]: ['ready', 'onReady'], - [UNMOUNTED]: ['detached', 'onUnload'], - [ONSHOW]: ['pageShow', 'onShow'], - [ONHIDE]: ['pageHide', 'onHide'], - [ONLOAD]: ['onLoad'], - [ONRESIZE]: ['onResize'], - [SERVERPREFETCH]: ['serverPrefetch'], - [REACTHOOKSEXEC]: ['reactHooksExec'] -} - -export const LIFECYCLE = { - APP_HOOKS, - PAGE_HOOKS, - COMPONENT_HOOKS -}