From 37a76e0ab72dffc0782784259af408b3f27b538c Mon Sep 17 00:00:00 2001 From: mackwang112 Date: Tue, 10 Mar 2026 16:37:50 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E9=94=80=E6=AF=81=E5=90=8E=E5=AF=BC=E8=87=B4rpx/vw/vh=E7=9B=B8?= =?UTF-8?q?=E5=BA=94=E5=BC=8F=E5=8D=95=E4=BD=8D=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/src/platform/patch/getDefaultOptions.ios.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/core/src/platform/patch/getDefaultOptions.ios.js b/packages/core/src/platform/patch/getDefaultOptions.ios.js index 62770ce107..55fac7ea0c 100644 --- a/packages/core/src/platform/patch/getDefaultOptions.ios.js +++ b/packages/core/src/platform/patch/getDefaultOptions.ios.js @@ -398,7 +398,7 @@ const triggerResizeEvent = (mpxProxy, sizeRef) => { } } -function usePageEffect (mpxProxy, pageId) { +function usePageEffect (mpxProxy, pageId, type) { const sizeRef = useRef(getSystemInfo()) useEffect(() => { @@ -415,7 +415,7 @@ function usePageEffect (mpxProxy, pageId) { triggerResizeEvent(mpxProxy, sizeRef) // 如果当前全局size与pagesize不一致,在show之后触发一次resize事件 - if (newVal === 'show' && global.__mpxPageSizeCountMap[pageId] !== global.__mpxSizeCount) { + if (type === 'page' && newVal === 'show' && global.__mpxPageSizeCountMap[pageId] !== global.__mpxSizeCount) { // 刷新__mpxPageSizeCountMap, 每个页面仅会执行一次,直接驱动render刷新 global.__mpxPageSizeCountMap[pageId] = global.__mpxSizeCount } @@ -427,7 +427,9 @@ function usePageEffect (mpxProxy, pageId) { } return () => { unWatch && unWatch() - del(global.__mpxPageSizeCountMap, pageId) + if (type === 'page') { + del(global.__mpxPageSizeCountMap, pageId) + } } }, []) } @@ -697,7 +699,7 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { } }) - usePageEffect(proxy, pageId) + usePageEffect(proxy, pageId, type) useEffect(() => { proxy.mounted() return () => { From 69ea9c180943ff690606fb430d1bb973782c7872 Mon Sep 17 00:00:00 2001 From: mackwang112 Date: Tue, 10 Mar 2026 16:39:05 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E8=BE=93=E5=87=BARN=20=E5=B1=8F?= =?UTF-8?q?=E5=B9=95=E5=B0=BA=E5=AF=B8=E5=8F=98=E5=8C=96=E6=97=B6=E4=BB=85?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E4=BE=9D=E8=B5=96rpx/vw/vh=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E5=BC=8F=E5=8D=95=E4=BD=8D=E7=9A=84=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builtInMixins/styleHelperMixin.ios.js | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js b/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js index 8113fb97cb..6c87870e63 100644 --- a/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js +++ b/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js @@ -12,8 +12,22 @@ global.__mpxPageSizeCountMap = reactive({}) global.__GCC = function (className, classMap, classMapValueCache) { if (!classMapValueCache.has(className)) { - const styleObj = classMap[className]?.(global.__formatValue) - styleObj && classMapValueCache.set(className, styleObj) + const originalDependentScreenSize = dependentScreenSize + dependentScreenSize = false + + let styleObj = classMap[className]?.(formatValue) + if (!styleObj) return + if (!styleObj._media?.length) { + styleObj = { + _default: styleObj + } + } + + // 记录是否依赖屏幕尺寸,在屏幕尺寸变化时决定是否重新渲染对应组件 + styleObj._dependentScreenSize = dependentScreenSize + dependentScreenSize = dependentScreenSize || originalDependentScreenSize + + classMapValueCache.set(className, styleObj) } return classMapValueCache.get(className) } @@ -79,12 +93,15 @@ const unit = { const empty = {} +// 记录style是否依赖屏幕尺寸 +let dependentScreenSize = false function formatValue (value, unitType) { if (!dimensionsInfoInitialized) useDimensionsInfo(global.__mpxAppDimensionsInfo) if (unitType === 'hairlineWidth') { return StyleSheet.hairlineWidth } if (unitType && typeof unit[unitType] === 'function') { + dependentScreenSize = true return unit[unitType](+value) } const matched = unitRegExp.exec(value) @@ -254,11 +271,11 @@ export default function styleHelperMixin () { return concat(staticClass, stringifyDynamicClass(dynamicClass)) }, __getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, hide) { + // 重置依赖标记 + dependentScreenSize = false const isNativeStaticStyle = staticStyle && isNativeStyle(staticStyle) let result = isNativeStaticStyle ? [] : {} const mergeResult = isNativeStaticStyle ? (...args) => result.push(...args) : (...args) => Object.assign(result, ...args) - // 使用一下 __getSizeCount 触发其 get - this.__getSizeCount() if (staticClass || dynamicClass) { // todo 当前为了复用小程序unocss产物,暂时进行mpEscape,等后续正式支持unocss后可不进行mpEscape @@ -267,17 +284,12 @@ export default function styleHelperMixin () { classString.split(/\s+/).forEach((className) => { let localStyle, appStyle if (localStyle = this.__getClassStyle?.(className)) { - if (localStyle._media?.length) { - mergeResult(localStyle._default, getMediaStyle(localStyle._media)) - } else { - mergeResult(localStyle) - } + mergeResult(localStyle._default, getMediaStyle(localStyle._media)) + // class style 计算可能触发缓存,需要单独在结果中记录是否依赖屏幕尺寸,不能直接使用全局变量。 + this.__dependentScreenSize = this.__dependentScreenSize || localStyle._dependentScreenSize } else if (appStyle = global.__getAppClassStyle?.(className)) { - if (appStyle._media?.length) { - mergeResult(appStyle._default, getMediaStyle(appStyle._media)) - } else { - mergeResult(appStyle) - } + mergeResult(appStyle._default, getMediaStyle(appStyle._media)) + this.__dependentScreenSize = this.__dependentScreenSize || appStyle._dependentScreenSize } else if (isObject(this.__props[className])) { // externalClasses必定以对象形式传递下来 mergeResult(this.__props[className]) @@ -319,6 +331,12 @@ export default function styleHelperMixin () { }) } const isEmpty = isNativeStaticStyle ? !result.length : isEmptyObject(result) + + // 仅在依赖屏幕尺寸时才触发__getSizeCount进行相应式关联,避免屏幕尺寸变化时不必要的性能损耗 + this.__dependentScreenSize = this.__dependentScreenSize || dependentScreenSize + if (this.__dependentScreenSize) { + this.__getSizeCount() + } return isEmpty ? empty : result } } From 97b32fc3fe02a4cd0c7700e406a8af16b28bfa82 Mon Sep 17 00:00:00 2001 From: mackwang112 Date: Tue, 10 Mar 2026 16:40:34 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=BE=93=E5=87=BA?= =?UTF-8?q?RN=20externalClasses=20=E5=8F=98=E5=8C=96=E6=97=B6=E6=9C=AA?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E7=BB=84=E4=BB=B6render?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/src/platform/builtInMixins/styleHelperMixin.ios.js | 4 ++-- packages/core/src/platform/patch/getDefaultOptions.ios.js | 5 +++++ packages/webpack-plugin/lib/loader.js | 3 ++- packages/webpack-plugin/lib/react/index.js | 4 +++- packages/webpack-plugin/lib/react/processScript.js | 5 +++-- packages/webpack-plugin/lib/react/script-helper.js | 4 +++- 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js b/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js index 6c87870e63..fea47aa337 100644 --- a/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js +++ b/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js @@ -290,9 +290,9 @@ export default function styleHelperMixin () { } else if (appStyle = global.__getAppClassStyle?.(className)) { mergeResult(appStyle._default, getMediaStyle(appStyle._media)) this.__dependentScreenSize = this.__dependentScreenSize || appStyle._dependentScreenSize - } else if (isObject(this.__props[className])) { + } else if (isObject(this.__mpxProxy.props[className])) { // externalClasses必定以对象形式传递下来 - mergeResult(this.__props[className]) + mergeResult(this.__mpxProxy.props[className]) } }) } diff --git a/packages/core/src/platform/patch/getDefaultOptions.ios.js b/packages/core/src/platform/patch/getDefaultOptions.ios.js index 55fac7ea0c..b1a2240cfe 100644 --- a/packages/core/src/platform/patch/getDefaultOptions.ios.js +++ b/packages/core/src/platform/patch/getDefaultOptions.ios.js @@ -639,6 +639,11 @@ export function getDefaultOptions ({ type, rawOptions = {}, currentInject }) { }) } const validProps = Object.assign({}, rawOptions.props, rawOptions.properties) + if (global.__externalClasses && global.__externalClasses.length > 0) { + global.__externalClasses.forEach((name) => { + validProps[name] = null + }) + } const { hasDescendantRelation, hasAncestorRelation } = checkRelation(rawOptions) if (rawOptions.methods) rawOptions.methods = wrapMethodsWithErrorHandling(rawOptions.methods) const defaultOptions = memo(forwardRef((props, ref) => { diff --git a/packages/webpack-plugin/lib/loader.js b/packages/webpack-plugin/lib/loader.js index cfb6f030a5..89c7960e20 100644 --- a/packages/webpack-plugin/lib/loader.js +++ b/packages/webpack-plugin/lib/loader.js @@ -38,7 +38,7 @@ module.exports = function (content) { return content } const { resourcePath, queryObj } = parseRequest(this.resource) - + const externalClasses = mpx.externalClasses || [] const packageRoot = queryObj.packageRoot || mpx.currentPackageRoot const packageName = packageRoot || 'main' const independent = queryObj.independent @@ -178,6 +178,7 @@ module.exports = function (content) { originalUsingComponents, componentGenerics, autoScope, + externalClasses, callback }) } diff --git a/packages/webpack-plugin/lib/react/index.js b/packages/webpack-plugin/lib/react/index.js index 4673d270f0..9969a34dd4 100644 --- a/packages/webpack-plugin/lib/react/index.js +++ b/packages/webpack-plugin/lib/react/index.js @@ -24,6 +24,7 @@ module.exports = function ({ originalUsingComponents, componentGenerics, autoScope, + externalClasses, callback }) { if (ctorType === 'app' && !queryObj.isApp) { @@ -95,7 +96,8 @@ module.exports = function ({ wxsModuleMap: templateRes.wxsModuleMap, localComponentsMap: jsonRes.localComponentsMap, localPagesMap: jsonRes.localPagesMap, - rnConfig + rnConfig, + externalClasses }, callback) } ], (err, scriptRes) => { diff --git a/packages/webpack-plugin/lib/react/processScript.js b/packages/webpack-plugin/lib/react/processScript.js index 9b88cb9b3a..d0d640b6fc 100644 --- a/packages/webpack-plugin/lib/react/processScript.js +++ b/packages/webpack-plugin/lib/react/processScript.js @@ -15,7 +15,8 @@ module.exports = function (script, { localPagesMap, rnConfig, componentGenerics, - genericsInfo + genericsInfo, + externalClasses }, callback) { const { appInfo, i18n } = loaderContext.getMpx() @@ -49,7 +50,7 @@ import { getComponent, getAsyncSuspense } from ${stringifyRequest(loaderContext, jsonConfig, rnConfig }) - output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, ctorType, jsonConfig, componentsMap, pagesMap, firstPage, hasApp }) + output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, ctorType, jsonConfig, componentsMap, pagesMap, firstPage, hasApp, externalClasses }) output += getRequireScript({ ctorType, script, loaderContext }) output += `export default global.__mpxOptionsMap[${JSON.stringify(moduleId)}]\n` } else { diff --git a/packages/webpack-plugin/lib/react/script-helper.js b/packages/webpack-plugin/lib/react/script-helper.js index a86e3ad72d..8347251dd2 100644 --- a/packages/webpack-plugin/lib/react/script-helper.js +++ b/packages/webpack-plugin/lib/react/script-helper.js @@ -150,7 +150,8 @@ function buildGlobalParams ({ firstPage, outputPath, genericsInfo, - hasApp + hasApp, + externalClasses }) { let content = '' if (ctorType === 'app') { @@ -165,6 +166,7 @@ global.__style = ${JSON.stringify(jsonConfig.style || 'v1')} global.__mpxPageConfig = ${JSON.stringify(jsonConfig.window)} global.__appComponentsMap = ${shallowStringify(componentsMap)} global.__preloadRule = ${JSON.stringify(jsonConfig.preloadRule)} +global.__externalClasses = ${JSON.stringify(externalClasses || [])} global.currentInject.pagesMap = ${shallowStringify(pagesMap)} global.currentInject.firstPage = ${JSON.stringify(firstPage)}\n` } else {