概述
現階段狀態管理V2版本還在試用階段,但是切實解決了很多在項目中使用V1導致的痛點問題,比如:
- 同一數據被多視圖代理時,無法同步數據修改。
- 無法做到深度觀測和深度監聽。
- 更新對象中某個數據時,會導致整個對象屬性都刷新,導致程序運行緩慢。
狀態管理V2版 裝飾器總覽
- @ObservedV2:裝飾class,使得裝飾的class具有深度監聽的能力。
- @Trace:只能在@ObservedV2裝飾的class中使用,被裝飾的屬性具有深度觀測的能力。
- @ComponentV2:裝飾頁面或者自定義組件。確定struct中可以使用V2版的裝飾器。
- @Local:裝飾的變量為當前組件的內部狀態,無法從外部初始化。
- @Param:裝飾的變量為組件的輸入,可以接受從外部傳入初始化并同步。
- @Once:裝飾的變量僅初始化時同步一次,需要與@Param一起使用。
- @Event:裝飾方法類型,作為組件輸出,可以通過該方法影響父組件中變量。
- @Monitor:裝飾器用于@ComponentV2裝飾的自定義組件或@ObservedV2裝飾的類中,能夠對狀態變量進行深度監聽。
- @Provider和@Consumer:用于跨組件層級雙向同步。
- @Computed:計算屬性,在被計算的值變化的時候,只會計算一次。主要應用于解決UI多次重用該屬性從而重復計算導致的性能問題
- !!語法:雙向綁定語法糖。
class的深入監測
使用@ObservedV2和@Trace兩種裝飾器,實現對屬性修改的觀測能力。具有以下特點:
- 被@Trace裝飾器裝飾的屬性變化時,僅會通知屬性關聯的組件進行刷新。
- @ObservedV2的類實例目前不支持使用JSON.stringify進行序列化。
@Trace可裝飾的變量
class中成員屬性。屬性的類型可以為number、string、boolean、class、Array、Date、Map、Set等類型。
@Trace可觀測API變化

使用
新建三個class,Father,Son,Son2。
- Son類被@ObservedV2裝飾器裝飾,age屬性被@Trace裝飾器裝飾。因此,age屬性的修改會引起UI更新。
- Father類沒有被@ObservedV2裝飾器修飾。
- Son2類繼承Son類,有一個沒有被@Trace裝飾器裝飾的Telephone屬性。
實現效果如下:

自定義組件
使用@ComponentV2裝飾器結合@Local、@Param、@Once、@Event、@Provider、@Consumer等裝飾器,實現自定義組件的狀態觀測。
使用時需要注意的點是:復雜類型常量重復賦值給狀態變量時,會重復觸發刷新,可能導致冗余刷新,因此,為了避免這種不必要的賦值和刷新,可以使用UIUtils.getTarget()獲取原始對象提前進行新舊值的判斷,當兩者相同時不執行賦值。
@Local
使用@Local裝飾對象,可以達到觀測對象本身變化的效果。
具有以下特點:
- 被@Local裝飾的變量無法從外部初始化,因此必須在組件內部進行初始化。
- @Local支持觀測number、boolean、string、Object、class等基本類型以及Array、Set、Map、Date等內嵌類型。
- @Local支持null、undefined以及聯合類型。
- 當裝飾的變量類型是內置類型時,可以觀察到變量整體賦值以及通過API調用帶來的變化。
代碼實現
新建一個class對象Info,其中name屬性被@Trace裝飾器裝飾,age屬性沒有被裝飾
實現效果如下:
- 點擊“change info1&info2”按鈕,Text1不會刷新,Text2會刷新。
- 點擊“修改info2的名字” 按鈕,Text2會刷新。
- 點擊“修改info2的年齡” 按鈕,Text2不會刷新。

@Param
具有以下特點:
- @Param裝飾的變量支持本地初始化,但是不允許在組件內部直接修改變量本身。
- 被@Param裝飾的變量能夠在初始化自定義組件時從外部傳入,當數據源也是狀態變量時,數據源的修改會同步給@Param。
- @Param可以接受任意類型的數據源,包括普通變量、狀態變量、常量、函數返回值等。
- @Param裝飾的變量變化時,會刷新該變量關聯的組件。
- @Param支持觀測number、boolean、string、Object、class等基本類型以及Array、Set、Map、Date等內嵌類型。
- 當裝飾簡單類型時,對變量的整體改變能夠觀測到;當裝飾對象類型時,僅能觀測對象整體的改變;當裝飾數組類型時,能觀測到數組整體以及數組元素項的改變;當裝飾Array、Set、Map、Date等內嵌類型時,可以觀測到通過API調用帶來的變化。
- @Param支持null、undefined以及聯合類型。

代碼實現
實現效果:

@Once
可以對@Param裝飾器的能力進行修改,具有以下的特點:
- @Once必須搭配@Param使用,單獨使用或搭配其他裝飾器使用都是不允許的。
- @Once不影響@Param的觀測能力,僅針對數據源的變化做攔截。
- @Once與@Param搭配使用時,可以在本地修改@Param變量的值。
@Event
使用@Event裝飾器裝飾回調方法,可以實現子組件對父組件傳遞的@Param裝飾的變量進行修改。類似子組件定義了一個委托函數,然后在父組件初始化的時候,對子組件的委托函數進行定義,子組件可以使用委托函數來實現想要的效果。
使用場景
更改父組件中的變量
實現效果:

@Provider和@Consumer
僅能修飾自定義組件內的屬性,不能修飾class的屬性。
和V1版本中的@Provide和@Consume有異曲同工之妙,主要用于跨組件層級數據雙向同步,但也存在不一樣的能力:

@Provider語法:
@Provider(alias?: string) varName : varType = initValue
- aliasName?: string,別名,缺省時默認為屬性名,向上查找最近的@Provider。
@Consumer語法:
@Consumer(alias?: string) varName : varType = initValue
- aliasName?: string,別名,缺省時默認為屬性名。
使用場景
子組件需要修改父組件的內容,可以使用 @Provider和@Consumer來實現。

@Monitor
- 用來監聽狀態變量變化,支持在類中與@ObservedV2、@Trace配合使用。
- 單個@Monitor裝飾器能夠同時監聽多個屬性的變化,當這些屬性在一次事件中共同變化時,只會觸發一次@Monitor的回調方法。
- @Monitor裝飾器具有深度監聽的能力,能夠監聽嵌套類、多維數組、對象數組中指定項的變化。對于嵌套類、對象數組中成員屬性變化的監聽要求該類被@ObservedV2裝飾且該屬性被@Trace裝飾
- 在繼承類場景中,可以在父子組件中對同一個屬性分別定義@Monitor進行監聽,當屬性變化時,父子組件中定義的@Monitor回調均會被調用。
裝飾器參數
字符串類型的對象屬性名。可同時監聽多個對象屬性,每個屬性以逗號隔開,例如@Monitor("prop1", "prop2")。可監聽深層的屬性變化,如多維數組中的某一個元素,嵌套對象或對象數組中的某一個屬性。
IMonitor類型的變量用作@Monitor裝飾方法的參數。
IMonitor類型參數
- dirty:Array :保存發生變化的屬性名。
- value:function:傳入參數為path?: string,返回IMonitorValue類型參數。
IMonitorValue類型參數
- before:T:監聽屬性變化之前的值。
- now:T:監聽屬性變化之后的當前值。
- path:string:監聽的屬性名。
使用場景
新建MonitorInfo類和被@ObservedV2裝飾器裝飾并繼承MonitorInfo類的MonitorInfo2。
實現效果如下:
- 整體替換的時候,都可以監測到。
- 沒有使用@ObservedV2和@Trace裝飾器的class屬性修改時無法被監測到。


總結
簡單講解了主要的V2裝飾器,其中還有一些裝飾在試用的時候出錯了,就沒有把使用方法總結出來。希望可以幫助到大家
浙公網安備 33010602011771號