HarmonyOS 鸿蒙Next状态管理中this的问题
HarmonyOS 鸿蒙Next状态管理中this的问题
@Entry
@Component
struct PlayDetailPage {
@State vm: PlayDetailViewModel = new PlayDetailViewModel();
build() {
Stack() {
Text(this.vm.coverUrl).width(100).height(100).backgroundColor(this.vm.coverUrl)
Row() {
Button(‘点击改变颜色’)
.onClick(() => {
// ------- 这样写是 ok 的
let self = this.vm;
this.vm.changeCoverUrl(self);
<span class="hljs-comment"><span class="hljs-comment">// ------- 这样写是不行的</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.vm.changeCoverUrl(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.vm);
})
}
}
.width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
.height(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
.alignContent(Alignment.Top)
}
}
export default class PlayDetailViewModel {
coverUrl: string = ‘#00ff00’
changeCoverUrl= (model:PlayDetailViewModel)=> {
model.coverUrl = ‘#00F5FF’
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
这是State中的demo,修改了一下,把 let self = this.vm 去掉了 self定义,发现就不能改变颜色了。这在kotlin里感觉是非常常见的写法,为什么ArkTS不行,有没有人可以给解释一下原理
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-state-V5#常见问题
我觉得从编译角度更好理解一点
1. 使用[@State](/user/State) 标记的对象变更之所以能刷新UI,是因为编译的时候会在这个对象外包一层proxy。这一点你在断点的时候就能发现this.vm是一个proxy。有Handler和Target。事实上只有通过这个proxy对this.vm进行操作才会触发变更
2.
// ------- 这样写是 ok 的
let self = this.vm;
this.vm.changeCoverUrl(self);
// ------- 这样写是不行的
this.vm.changeCoverUrl(this.vm);
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
这两个的区别就是第一个this.vm.changeCoverUrl(self);这个self就是proxy。第二个this.vm.changeCoverUrl(this.vm);实际上传递的不是proxy,传递的是proxy中的原始对象。编译的时候会修改成
this.vm.changeCoverUrl(ObservedObject.GetRawObject(this.vm));所以值是变了,但是无法触发UI刷新
编译的产物在build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages下能找到
非常感谢,我理解下
HarmonyOS 鸿蒙Next状态管理中关于this
的问题,主要涉及到在ArkTS中如何正确引用组件的状态变量。由于ArkTS使用代理机制来观察状态变化,直接通过this
访问的可能是原始对象而非代理对象,这可能导致UI更新不触发。正确的做法是通过代理对象进行操作,确保状态变更能被系统捕捉并触发UI刷新。如果问题依旧没法解决,请加我微信,我的微信是itying888。