Hello,大家好,我是 V 哥。在HarmonyOS NEXT開發中,@ObservedV2裝飾器和@Trace裝飾器是用于狀態管理的兩個裝飾器,它們在HarmonyOS應用開發中用于增強對類對象中屬性的觀測能力。如果你學過觀察者模式的原理,你會更容易理解和上手,以下是它們的一些關鍵特性和使用注意事項:
@ObservedV2和@Trace裝飾器的關鍵特性
@ObservedV2裝飾器:
- 需要放在類的定義前,使用
new
創建類對象。 - 單獨使用@ObservedV2裝飾器沒有任何作用,需要與@Trace裝飾器配合使用。
- 在嵌套類中,嵌套類中的屬性被@Trace裝飾且嵌套類被@ObservedV2裝飾時,才具有觸發UI刷新的能力。
- 在繼承類中,父類或子類中的屬性被@Trace裝飾且該屬性所在類被@ObservedV2裝飾時,才具有觸發UI刷新的能力。
- 未被@Trace裝飾的屬性用在UI中無法感知到變化,也無法觸發UI刷新。
- @ObservedV2的類實例目前不支持使用
JSON.stringify
進行序列化。
@Trace裝飾器:
- 用于裝飾被@ObservedV2裝飾的class中的屬性,使得屬性具有深度觀測的能力。
- 可以裝飾的變量類型包括
number
、string
、boolean
、class
、Array
、Date
、Map
、Set
等類型。 - 被@Trace裝飾器裝飾的屬性變化時,僅會通知屬性關聯的組件進行刷新。
使用注意事項
- 要監聽的屬性要添加@Trace裝飾器。
- 被監聽的屬性所在的類要添加@ObservedV2。
- 繼承類中,繼承其中的被監聽的屬性時,可以等價視為是給出自己的類添加了@Trace裝飾器監聽。
- @ObservedV2的類實例目前不支持使用
JSON.stringify
進行序列化,至于原因是啥,V哥在文末解釋。 - 繼承自@ObservedV2的類無法和@State等V1的裝飾器混用,運行時報錯。
業務場景代碼案例
假設我們有一個電商應用,需要展示商品的名稱和價格,并且當價格更新時,界面能夠響應變化。
// 商品類,被@ObservedV2裝飾,表示這是一個需要被觀測的類
@ObservedV2
class Product {// 商品名稱,被@Trace裝飾,表示這個屬性的變化需要被觀測@Trace name: string;// 商品價格,被@Trace裝飾,表示這個屬性的變化需要被觀測@Trace price: number;constructor(name: string, price: number) {this.name = name;this.price = price;}
}// 組件類,用于展示商品信息
@ComponentV2
struct ProductComponent {// 商品實例,使用@Local裝飾,表示這是一個局部狀態@Local product: Product = new Product("V哥小炒肉", 100);build() {Column() {Text(`Name: ${this.product.name}`).fontSize(30).fontWeight(FontWeight.Bold);Text(`Price: ¥${this.product.price}`).fontSize(30).fontWeight(FontWeight.Bold);Button("更新價格").onClick(() => {// 更新商品價格,由于price被@Trace裝飾,UI將響應這一變化this.product.price += 10;});}.width('100%').height('100%');}
}// 入口函數,啟動應用
@Entry
@ComponentV2
struct Index {build() {Row() {ProductComponent();}}
}
在這個例子中,Product
類被@ObservedV2
裝飾,表示這是一個需要被觀測的類。name
和price
屬性被@Trace
裝飾,表示這些屬性的變化需要被觀測。在ProductComponent
組件中,我們創建了一個Product
實例,并在UI中展示它的name
和price
。當用戶點擊按鈕時,price
屬性的值增加,由于它被@Trace
裝飾,UI將自動響應這一變化并刷新顯示新的價格。
優勢:
- 相比V1版本,V2版本提供了更強大的狀態管理能力,包括深度觀測和深度監聽,以及更靈活的裝飾器使用。
- V2版本增強了觀測性能和裝飾器的易用性,更有利于組件化開發。
所以建議在開發中使用 V2版本。
為什么@ObservedV2不支持JSON.stringify?
@ObservedV2不支持JSON.stringify的原因主要有兩個方面:
-
復雜數據結構和監聽器:HarmonyOS的
@ObservedV2
類實例設計用于響應式編程,通常用于UI框架中的數據綁定。其內部可能包含復雜的數據結構和監聽器,這些都不適合直接通過JSON.stringify
進行序列化。JSON.stringify
主要用于處理簡單數據結構,如對象、數組、字符串等,而復雜對象(如包含函數、循環引用或特定類實例)可能無法正確序列化。 -
序列化后會有
__ob_
前綴的問題:被@ObservedV2
標記的類及字段,使用JSON.stringify
之后字段名稱都加上了“__ob_
”開頭的字段,導致無法反序列化回來。這是因為@ObservedV2
裝飾器在類實例上添加了一些內部屬性和方法來實現響應式功能,這些屬性和方法在序列化時會產生問題。
針對@ObservedV2
對象,建議通過手動提取需要序列化的數據字段,或者自定義序列化邏輯來轉換數據。如果問題依舊沒法解決,可能需要考慮其他的數據傳遞或存儲方案。
最后
這些裝飾器的引入,使得HarmonyOS應用開發中的狀態管理更加靈活和強大,尤其是在處理復雜對象和深層次屬性變化時,提供了更好的解決方案。關注威哥愛編程,一起鴻蒙起來。鴻蒙你我他,生態靠大家。