HarmonyOS鸿蒙Next中碰到一个很奇怪的问题关于WithTheme的,使用@LocalBuilder它样式不更新,使用@Builder它的样式更新但是this指向又有问题
HarmonyOS鸿蒙Next中碰到一个很奇怪的问题关于WithTheme的,使用@LocalBuilder它样式不更新,使用@Builder它的样式更新但是this指向又有问题

点击按钮切换样式,builder1是@Builder它的颜色样式更新了,但是由于this指向的问题它拿不到样式的颜色值(builder1是按钮上显示的是undefined);
builder2是@LocalBuilder它的颜色样式没有更新,由于this指向没问题它拿到了样式的颜色值。
这个builder1和builder2都属于WithTheme下的子组件,按道理来讲builder1和builder2都应该更新样式的
```typescript
import { CustomColors, CustomTheme } from '[@kit](/user/kit).ArkUI';
class AppColors implements CustomColors {
fontPrimary: ResourceColor = Color.Blue;
backgroundEmphasize: ResourceColor = Color.Blue;
}
class AppColorsSec implements CustomColors {
fontPrimary: ResourceColor = Color.Orange;
backgroundEmphasize: ResourceColor = Color.Orange;
}
class AppTheme implements CustomTheme {
public colors: AppColors = new AppColors();
}
class AppThemeSec implements CustomTheme {
public colors: AppColors = new AppColorsSec();
}
[@Entry](/user/Entry)
[@Component](/user/Component)
struct DisplayPage {
[@State](/user/State) customTheme: CustomTheme = new AppTheme();
message: string = '设置应用局部页面自定义主题风格';
count = 0;
build() {
WithTheme({ theme: this.customTheme }) {
Column() {
Text('WithTheme')
.fontSize(30)
.margin({ bottom: 10 })
Text(this.message)
.margin({ bottom: 10 })
Button('change theme').onClick(() => {
this.count++;
if (this.count > 1) {
this.count = 0;
}
switch (this.count) {
case 0:
this.customTheme = new AppTheme();
break;
case 1:
this.customTheme = new AppThemeSec();
break;
}
})
MyComponent({
view1: this.builder1,
view2: this.builder2,
}).margin({ top: 30 })
}.width('100%')
.height('100%')
}
}
[@Builder](/user/Builder)
builder1() {
Column() {
Text('builder1')
.fontSize(30)
.margin({ top: 30, bottom: 10 })
Button(`backgroundEmphasize:${this.customTheme?.colors?.backgroundEmphasize}`)
}
.width('100%')
}
[@LocalBuilder](/user/LocalBuilder)
builder2() {
Column() {
Text('builder2')
.fontSize(30)
.margin({ top: 30, bottom: 10 })
Button(`backgroundEmphasize:${this.customTheme?.colors?.backgroundEmphasize}`)
}
.width('100%')
}
}
[@Component](/user/Component)
struct MyComponent {
[@BuilderParam](/user/BuilderParam) view1: () => void
[@BuilderParam](/user/BuilderParam) view2: () => void
build() {
Column() {
this.view1()
this.view2()
}.width('100%')
}
}
更多关于HarmonyOS鸿蒙Next中碰到一个很奇怪的问题关于WithTheme的,使用@LocalBuilder它样式不更新,使用@Builder它的样式更新但是this指向又有问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
使用箭头函数呢?
更多关于HarmonyOS鸿蒙Next中碰到一个很奇怪的问题关于WithTheme的,使用@LocalBuilder它样式不更新,使用@Builder它的样式更新但是this指向又有问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
箭头函数和@LocalBuilder的效果是一样的,this指向没问题样式就有问题,样式没问题this指向就错了。
在HarmonyOS Next中,@LocalBuilder
和@Builder
的差异在于作用域。@LocalBuilder
不会跟随主题更新,因为它绑定的是组件初始状态。@Builder
能响应主题变化,但会丢失原始组件上下文(this)。这是设计机制差异,不是bug。如需同时保留this引用和主题响应,可尝试将this显式传递给@Builder
参数。两种装饰器的this绑定逻辑在ArkUI框架层已固定。
这是一个关于HarmonyOS Next中WithTheme组件与Builder/LocalBuilder作用域的问题。主要区别在于:
-
@Builder是全局构建器,会导致
this
指向丢失,因此虽然样式能更新,但无法通过this
访问到customTheme实例。 -
@LocalBuilder是局部构建器,能正确保持
this
指向,但由于其构建过程发生在父组件初始化阶段,导致无法响应WithTheme的更新。
解决方案:
- 对于需要访问
this
的场景,建议使用@LocalBuilder并通过参数传递theme值 - 或者将Builder内容直接内联到WithTheme作用域内,避免使用构建器
示例修改:
[@LocalBuilder](/user/LocalBuilder)
builder2(theme: CustomTheme) {
Column() {
Text('builder2')
Button(`backgroundEmphasize:${theme?.colors?.backgroundEmphasize}`)
}
}
这样既能保持this
指向,又能响应主题更新。