Skip to content

Commit 48750bf

Browse files
committed
feat: 输出RN 屏幕尺寸变化时仅刷新依赖rpx/vw/vh响应式单位的组件
1 parent ccbd4f7 commit 48750bf

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,22 @@ global.__mpxPageSizeCountMap = reactive({})
1212

1313
global.__GCC = function (className, classMap, classMapValueCache) {
1414
if (!classMapValueCache.has(className)) {
15-
const styleObj = classMap[className]?.(global.__formatValue)
16-
styleObj && classMapValueCache.set(className, styleObj)
15+
const originalDependentScreenSize = dependentScreenSize
16+
dependentScreenSize = false
17+
18+
let styleObj = classMap[className]?.(formatValue)
19+
if (!styleObj) return
20+
if (!styleObj._media?.length) {
21+
styleObj = {
22+
_default: styleObj
23+
}
24+
}
25+
26+
// 记录是否依赖屏幕尺寸,在屏幕尺寸变化时决定是否重新渲染对应组件
27+
styleObj._dependentScreenSize = dependentScreenSize
28+
dependentScreenSize = dependentScreenSize || originalDependentScreenSize
29+
30+
classMapValueCache.set(className, styleObj)
1731
}
1832
return classMapValueCache.get(className)
1933
}
@@ -79,12 +93,15 @@ const unit = {
7993

8094
const empty = {}
8195

96+
// 记录style是否依赖屏幕尺寸
97+
let dependentScreenSize = false
8298
function formatValue (value, unitType) {
8399
if (!dimensionsInfoInitialized) useDimensionsInfo(global.__mpxAppDimensionsInfo)
84100
if (unitType === 'hairlineWidth') {
85101
return StyleSheet.hairlineWidth
86102
}
87103
if (unitType && typeof unit[unitType] === 'function') {
104+
dependentScreenSize = true
88105
return unit[unitType](+value)
89106
}
90107
const matched = unitRegExp.exec(value)
@@ -254,11 +271,11 @@ export default function styleHelperMixin () {
254271
return concat(staticClass, stringifyDynamicClass(dynamicClass))
255272
},
256273
__getStyle (staticClass, dynamicClass, staticStyle, dynamicStyle, hide) {
274+
// 重置依赖标记
275+
dependentScreenSize = false
257276
const isNativeStaticStyle = staticStyle && isNativeStyle(staticStyle)
258277
let result = isNativeStaticStyle ? [] : {}
259278
const mergeResult = isNativeStaticStyle ? (...args) => result.push(...args) : (...args) => Object.assign(result, ...args)
260-
// 使用一下 __getSizeCount 触发其 get
261-
this.__getSizeCount()
262279

263280
if (staticClass || dynamicClass) {
264281
// todo 当前为了复用小程序unocss产物,暂时进行mpEscape,等后续正式支持unocss后可不进行mpEscape
@@ -267,20 +284,15 @@ export default function styleHelperMixin () {
267284
classString.split(/\s+/).forEach((className) => {
268285
let localStyle, appStyle
269286
if (localStyle = this.__getClassStyle?.(className)) {
270-
if (localStyle._media?.length) {
271-
mergeResult(localStyle._default, getMediaStyle(localStyle._media))
272-
} else {
273-
mergeResult(localStyle)
274-
}
287+
mergeResult(localStyle._default, getMediaStyle(localStyle._media))
288+
// class style 计算可能触发缓存,需要单独在结果中记录是否依赖屏幕尺寸,不能直接使用全局变量。
289+
this.__dependentScreenSize = this.__dependentScreenSize || localStyle._dependentScreenSize
275290
} else if (appStyle = global.__getAppClassStyle?.(className)) {
276-
if (appStyle._media?.length) {
277-
mergeResult(appStyle._default, getMediaStyle(appStyle._media))
278-
} else {
279-
mergeResult(appStyle)
280-
}
281-
} else if (isObject(this.__props[className])) {
291+
mergeResult(appStyle._default, getMediaStyle(appStyle._media))
292+
this.__dependentScreenSize = this.__dependentScreenSize || appStyle._dependentScreenSize
293+
} else if (isObject(this.__mpxProxy.props[className])) {
282294
// externalClasses必定以对象形式传递下来
283-
mergeResult(this.__props[className])
295+
mergeResult(this.__mpxProxy.props[className])
284296
}
285297
})
286298
}
@@ -319,6 +331,12 @@ export default function styleHelperMixin () {
319331
})
320332
}
321333
const isEmpty = isNativeStaticStyle ? !result.length : isEmptyObject(result)
334+
335+
// 仅在依赖屏幕尺寸时才触发__getSizeCount进行相应式关联,避免屏幕尺寸变化时不必要的性能损耗
336+
this.__dependentScreenSize = this.__dependentScreenSize || dependentScreenSize
337+
if (this.__dependentScreenSize) {
338+
this.__getSizeCount()
339+
}
322340
return isEmpty ? empty : result
323341
}
324342
}

0 commit comments

Comments
 (0)