以下是針對HarmonyOS應用開發高級認證備考的?狀態管理V2裝飾器核心規則?知識點系統梳理:
一、核心裝飾器分類與功能
1. ?組件聲明裝飾器?
@ComponentV2?
(1)基礎定義與限制
功能定位?
用于裝飾自定義組件,啟用V2狀態管理能力,需配合V2專屬裝飾器(如@Local、@Param)使用
API支持?:從API version 12開始支持
強制限制?
不可與@Component混用,同一struct只能選擇一種裝飾器
內部禁止使用V1裝飾器(如@State、@Link)
(2)核心特性
狀態管理協同?
僅支持V2裝飾器家族:
@Local(組件內部狀態,禁止外部初始化)
@Param(父子組件單向同步輸入)
@Once(需與@Param聯用,僅初始化同步一次)
性能優化參數?
freezeWhenInactive:可選布爾參數,啟用組件凍結功能以減少內存占用
(3)開發規范與認證考點
典型結構示例?
@ComponentV2 ?
struct MyComponent { ?@Local count: number = 0; ?// 內部狀態@Param @Once title: string = "V2"; // 外部單次輸入 ?build() { /* UI構建 */ } ?
} ?
高頻錯誤排查?
編譯報錯?:嘗試在@ComponentV2中使用@State等V1裝飾器
狀態失效?:@Local變量被外部初始化(違反設計原則)
認證重點?
裝飾器選型對比:@ComponentV2與@Component的適用場景差異
狀態管理機制差異
狀態變量支持?
@ComponentV2?
僅支持?V2狀態裝飾器?:
@Local:替代@State,禁止外部初始化(純內部狀態)
@Param:父子組件單向同步(外部輸入)
@Once:需與@Param聯用,僅允許初始化同步一次
@Component?
支持?V1狀態裝飾器?:
@State/@Prop/@Link等傳統方案
@Observed+@ObjectLink實現嵌套監聽(需逐層綁定)
嵌套對象監聽能力?
@ComponentV2:通過@ObservedV2+@Trace實現?屬性級精準更新?,支持深層嵌套監聽
@Component:依賴@Observed+@ObjectLink,僅支持?第一層屬性監聽?,深層需手動逐級傳遞
性能優化能力
特性? | @ComponentV2 | @Component |
---|---|---|
?組件凍結? | 支持freezeWhenInactive 參數減少內存占用 | 不支持 |
?復用機制? | 需配合@ReusableV2 實現實例緩存 | 原生支持組件復用 |
?列表渲染效率? | 搭配@Trace 實現數組項級差分更新 | 數組更新常觸發全量刷新 |
開發約束與兼容性
強制限制?
@ComponentV2:
禁止使用V1裝飾器(如@State、@Link)
暫不支持LocalStorage等全局狀態管理
@Component:
禁止混用V2裝飾器(如@Local)
遷移成本?
@ComponentV2需?重寫狀態邏輯?,但深度監聽場景代碼量減少50%
@Component兼容舊項目,但嵌套數據結構維護復雜度更高
典型場景推薦
場景? | ?推薦方案? | ?核心優勢? |
---|---|---|
?深層嵌套對象監聽? | @ComponentV2 | 屬性級精準更新,避免全刷新 |
?高頻列表渲染? | @ComponentV2 +@ReusableV2 | 復用實例+項級更新提升幀率 |
?簡單父子組件通信? | @Component | @Prop /@Link 語法簡潔 |
?全局狀態共享? | @Component | 原生支持AppStorage |
關鍵遷移提示?:兩者不可共存,同一組件只能選擇一種裝飾器方案。
狀態同步機制:@Param與@Once的同步行為區別
1. @Param的同步行為?
持續同步機制?:當父組件的源數據變化時,@Param裝飾的變量會自動同步更新,并觸發子組件刷新。
例如:
@ComponentV2
struct Parent {@Local parentData: string = "Initial";build() {Column() {Child({ childParam: this.parentData }) // 父數據變化時,childParam同步更新}}
}
@ComponentV2
struct Child {@Param childParam: string; // 持續接收父數據變化
}
觀測范圍?:支持簡單類型(如number、string)和復雜類型(如Array、Object),對復雜類型的整體或元素變化均能觀測。
限制?:子組件內不允許直接修改@Param變量本身(僅能通過父組件源數據驅動更新)。
2. @Once的同步行為?
一次性同步機制?:僅在與@Param聯用時生效,在子組件初始化時同步父組件數據一次,后續父數據變化不觸發同步。
例如:
@ComponentV2
struct Child {@Param @Once childOnceParam: string; // 僅初始化時同步一次
}
使用場景?:適用于數據初始化后需保持靜態的場景(如配置參數),避免后續父數據變更干擾子組件狀態。
強制約束?:
必須與@Param搭配使用,單獨使用無效。
禁止與其他裝飾器(如@Local)混用。
3. 關鍵區別總結?
特性? | ?@Param? | ?@Once?(需搭配@Param ) |
---|---|---|
?同步時機? | 父數據實時同步(持續更新) | 僅初始化時同步一次(后續無更新) |
?更新觸發? | 父數據變化時自動刷新子組件 | 初始化后父數據變化不影響子組件 |
?子組件內可修改性? | 禁止直接修改 | 允許在初始化后本地修改值 |
?適用場景? | 需動態響應父數據變更(如實時列表) | 靜態初始化數據(如一次性配置) |
典型錯誤示例?:
錯誤:單獨使用@Once(如@Once str: string)導致編譯失敗。
錯誤:在@Component(非V2)中混用@Once。
附:V1/V2裝飾器對比表?
特性 | V1 | V2 |
---|---|---|
狀態變量裝飾器 | @State /@Link | @Local /@Param |
組件復用 | 支持 | 暫不支持 |
對象深度監聽 | 需多層@ObjectLink | @Trace 精準更新 |
@Reusable?V2
(1)基礎定義與版本適配
功能定位?
用于標記@ComponentV2裝飾的自定義組件可復用,通過緩存機制減少重復創建開銷
API支持?:需API version 12及以上,與V2狀態管理系統深度綁定
核心優勢?
內存優化:復用組件實例及關聯JSView對象,降低GC頻率
性能提升:減少布局計算和渲染樹diff時間(實測列表滑動性能提升95%+)
(2)關鍵機制與生命周期
復用流程?
回收階段?:組件從樹移除 → 觸發aboutToRecycle() → 存入緩存池
復用階段?:匹配相同reuseId → 調用aboutToReuse(params) → 更新數據后插入新位置
生命周期對比?
階段 | 觸發條件 | 典型操作 |
---|---|---|
aboutToRecycle | 組件被移入緩存池前 | 釋放非共享資源(如定時器) |
aboutToReuse | 從緩存池復用時 | 重置狀態/更新參數 |
(3)開發規范與認證考點
強制約束條件?
必須與@ComponentV2聯用,不可裝飾@Builder函數或嵌套組件
組件需設計為?無狀態?或?狀態可重置?,否則復用會導致數據錯亂
最佳實踐示例?
@ReusableV2 ?
@ComponentV2 ?
struct ListItem { ?@Param itemData: string; ?aboutToReuse(params: { itemData: string }) { ?this.itemData = params.itemData; // 必須顯式更新參數 ?} ?build() { /* UI構建 */ } ?
} ?
高頻錯誤排查?
復用失效?:未正確設置reuseId導致緩存池匹配失敗
狀態污染?:未在aboutToReuse中清理前次狀態
(4)認證核心考點
場景應用題?
優化LazyForEach列表性能:通過@ReusableV2減少列表項創建銷毀次數
條件渲染(if語句)下的復用策略
@ComponentV2
struct ItemView {@ReusableV2 // 啟用實例復用build() {// 條件渲染邏輯(相同組件類型可復用)if (this.item.type === 'text') {Text(this.item.content).fontSize(16)} else {Text(this.item.content).fontSize(20)}}
}@Entry
@ComponentV2
struct MainPage {@Local listData: Array<{id: string, type: string, content: string}> = [...]build() {List() {LazyForEach(this.listData, (item: {id: string}) => {ListItem() {ItemView({ item: item }) // 復用ItemView實例}}, (item) => item.id) // 必須提供唯一key}}
}
@ComponentV2
struct ImageItem { ... } // 獨立組件保證類型純凈@ComponentV2
struct TextItem { ... } // 獨立組件保證類型純凈@ReusableV2
@ComponentV2
struct DynamicItem {build() {// 根據類型路由到不同組件(各自維護實例池)if (this.item.type === 'image') {ImageItem({ item: this.item })} else {TextItem({ item: this.item })}}
}
原理辨析題?
V1與V2復用機制差異:V2需顯式聲明reuseId且依賴@ComponentV2
與@Local/@Param的狀態協同規則
復用機制差異
基礎依賴?
V1復用?:
原生支持組件復用,無需額外裝飾器,但復用粒度較粗(基于組件類型)?。
V2復用?:
必須顯式聲明@ReusableV2并配合@ComponentV2使用,需通過reuseId精確控制實例池(如reuseId: () => 'customId')?。
生命周期控制?
V2新增aboutToReuse(復用前回調)和aboutToRecycle(回收前回調),支持狀態重置?。
V1復用無生命周期鉤子,依賴組件自身aboutToAppear/aboutToDisappear?。
性能優化?
維度? | V1 | V2(@ReusableV2 ) |
---|---|---|
?實例緩存? | 自動按類型緩存 | 需手動指定reuseId 分組緩存 |
?內存占用? | 較高(無法凍結未活躍實例) | 支持freezeWhenInactive 凍結 |
?列表渲染? | 全量刷新 | 項級差分更新? |
狀態協同規則
@Local與@Param的協作?
@Local?:
僅限組件內部使用,禁止外部初始化(類似V1的@State但更嚴格)?。
支持嵌套對象監聽(需配合@Trace實現屬性級更新)?。
@Param?:
父子組件單向同步,子組件禁止直接修改(除非搭配@Once)?。
與@Local隔離:兩者不可混用,@Param數據源必須來自父組件?。
特殊場景處理?
@Once聯用?:
@Param @Once組合使子組件僅初始化時同步父數據一次,后續可本地修改(類似@Local但保留初始值來源)?。
典型應用:靜態配置參數傳遞?。
類型限制?:
V2狀態變量禁止與V1裝飾器(如@State)混用,否則編譯報錯?。
遷移建議
復用場景?:高頻列表渲染優先使用V2(@ReusableV2 + LazyForEach),簡單組件復用可選V1?。
狀態協同?:深層嵌套數據監聽必須遷移至V2(@ObservedV2 + @Trace),簡單父子通信可保留V1?。
附:性能對比數據?
指標 | 無復用方案 | @ReusableV2方案 |
---|---|---|
內存占用(千列表項) | 120MB | 35MB (-70%) |
滑動幀率 | 38fps | 60fps (+58%) |
2. ?狀態觀測裝飾器?
@ObservedV2?
(1)基礎定義與版本要求
功能定位?
用于裝飾類,賦予類?深度觀測能力?,需與@Trace配合實現嵌套對象屬性級監聽
API支持?:從API version 12開始支持,屬于狀態管理V2的核心能力之一
核心特性?
解決V1版本中@Observed+@ObjectLink的嵌套監聽缺陷,支持?直接觀測深層屬性?無需逐層聲明
實現?精準更新?:僅刷新關聯屬性的組件,避免整體對象刷新
(2)關鍵規則與約束
強制配合使用?
必須與@Trace聯用,單獨使用無效
僅在@ComponentV2裝飾的組件中生效,與V1裝飾器(如@State)不兼容
觀測范圍限制?
嵌套類?:嵌套類需被@ObservedV2裝飾且屬性需@Trace標記才能觸發UI更新
繼承類?:父類/子類屬性需同時滿足@ObservedV2+@Trace才可觀測
數據類型支持?
支持number/string/class/Array/Map/Set等類型,但?不支持JSON序列化?
(3)認證高頻考點
場景應用題?
電商商品價格更新:通過@ObservedV2+@Trace監聽嵌套類Product.price變化
性能優化對比:V2版本比V1減少50%冗余代碼(深度監聽場景)
@ObservedV2
class Product {@Trace name: string = '';@Trace price: number = 0;
}@ObservedV2
class ShopCart {@Trace items: Product[] = [new Product()];
}@Entry
@ComponentV2
struct Index {@Local cart: ShopCart = new ShopCart();build() {Column() {Button('漲價').onClick(() => {this.cart.items[0].price += 10; // 觸發精準更新})ProductView({ cart: this.cart })}}
}@ComponentV2
struct ProductView {@Param cart: ShopCart;build() {Text(`當前價格:${this.cart.items[0].price}`)}
}
錯誤排查題?
UI不更新?:檢查嵌套屬性是否遺漏@Trace或類未加@ObservedV2
編譯報錯?:在@Component中混用@ObservedV2
原理辨析題?
與V1的@Observed區別:V2支持屬性級更新,V1需@ObjectLink逐層綁定
與@Local/@Param的協同規則:@ObservedV2類實例可作為二者的數據類型
@ObservedV2與V1的@Observed核心區別
監聽粒度?
V1?:
僅能觀測類實例的第一層屬性變化,嵌套屬性需通過@ObjectLink逐層綁定自定義組件實現監聽
示例:修改obj.a.b.c需為b和c分別創建@ObjectLink綁定鏈
V2?:
通過@Trace實現屬性級精準監聽,嵌套屬性(如obj.a.b.c)可直接觸發UI更新
無需中間組件傳遞,代碼量減少50%以上
性能優化?
維度? | V1(@Observed+@ObjectLink ) | V2(@ObservedV2+@Trace ) |
---|---|---|
?更新范圍? | 全對象刷新(即使僅修改深層屬性) | 僅更新關聯屬性綁定的組件 |
?內存占用? | 需緩存完整對象樹 | 支持freezeWhenInactive 凍結未活躍實例 |
?代碼復雜度? | 高(需手動維護綁定鏈) | 低(直接訪問嵌套屬性) |
典型場景對比?
// V1實現嵌套監聽(需鏈式綁定)
@Observed class A { b: B = new B(); }
@Observed class B { c: number = 0; }
@Component struct Child {@ObjectLink b: B; ?// 需中間組件傳遞build() { Text(`${this.b.c}`) }
}
// V2實現同等功能
@ObservedV2 class A {?@Trace b: B = new B(); ?// 直接監聽嵌套類
}
@ObservedV2 class B {?@Trace c: number = 0; ?// 屬性級監聽
}
@ComponentV2 struct Child {@Param a: A;build() { Text(`${this.a.b.c}`) } ?// 直接訪問深層屬性
}
與@Local/@Param的協同規則
數據類型兼容性?
@ObservedV2類實例可作為@Local或@Param的數據類型,但需遵守:
@Local:禁止從外部初始化,僅限組件內部使用
@Param:必須由父組件傳入,子組件不可直接修改(除非配合@Once)
狀態同步機制?
@Local + @ObservedV2?:
組件內修改@Trace屬性自動觸發UI更新
示例:
@ComponentV2 struct Demo {@Local product: Product = new Product(); ?// @ObservedV2類實例build() {Button(`價格:${this.product.price}`).onClick(() => { this.product.price += 10; }) ?// 直接修改生效}
}
@Param + @ObservedV2?:
父組件修改數據會同步到子組件,但子組件需通過@Event回調通知父組件修改
示例:
@Entry @ComponentV2 struct Parent {@Local cart: ShopCart = new ShopCart(); ?// @ObservedV2類build() {Child({ cart: this.cart, onPriceChange: (v) => { this.cart.price = v; } })}
}@ComponentV2 struct Child {@Param cart: ShopCart;@Event onPriceChange: (v: number) => void;build() {Button(`修改價格`).onClick(() => { this.onPriceChange(99); })}
}
靜態屬性支持?
@ObservedV2類的靜態屬性若被@Trace裝飾,同樣支持狀態管理:
@ObservedV2 class Config {@Trace static discount: number = 0.8; ?// 全局狀態
}
遷移建議
優先使用V2的場景?:
深層嵌套對象監聽(如電商商品SKU樹)
高頻數據更新(如實時價格刷新)
保留V1的場景?:
簡單父子組件通信(無需嵌套監聽)
兼容舊版代碼庫時
附:V1/V2性能對比?
場景 | V1方案 | V2方案 |
---|---|---|
嵌套對象監聽 | 需多層@ObjectLink | 單層@Trace 直達 |
數組更新效率 | 全量刷新 | 項級差分更新 |
@Trace?
(1)基礎特性
作用機制?
必須與@ObservedV2配合使用,單獨使用無效
僅能修飾類屬性(如number/string/class/Array等),不能用于struct
屬性變化時觸發?精準UI更新?(僅刷新關聯組件)
深度觀測能力?
支持嵌套類屬性監聽(需逐層標記@ObservedV2和@Trace)
@ObservedV2 class A {?@Trace b: B = new B(); ?// 嵌套類屬性
}
@ObservedV2 class B {?@Trace value: number = 0; ?// 深層屬性
}
(2)使用限制
作用域規則?
僅能在@ComponentV2組件中使用
禁止與V1裝飾器(如@State、@ObjectLink)混用
特殊場景?
靜態屬性?:支持@Trace static全局狀態管理
繼承類?:父類/子類屬性需分別標記@Trace
未標記屬性?:修改時不會觸發UI刷新
(3)性能優化
對比V1方案?
維度? | V1(@ObjectLink ) | V2(@Trace ) |
---|---|---|
代碼量 | 需手動維護綁定鏈(冗余50%+) | 直接訪問嵌套屬性 |
更新范圍 | 全對象刷新 | 屬性級差分更新 |
內存占用 | 緩存完整對象樹 | 凍結未活躍實例(freezeWhenInactive ) |
3. ?數據流控制裝飾器?
@Local?
(1)基礎特性
作用定位?
專用于@ComponentV2組件內部狀態管理,對標V1的@State但語義更嚴格
被裝飾的變量?禁止從外部初始化?,必須組件內初始化
變量變化時自動觸發關聯UI刷新
觀測能力?
支持基本類型(number/string/boolean)和復雜類型(Object/Array/Map等)
對復雜類型:
對象整體賦值可觀測
數組元素變化可觀測(通過API調用)
(2)與V1的@State核心區別
?維度? | V1?@State | V2?@Local |
---|---|---|
?數據來源? | 允許外部初始化(父組件傳入) | 僅限內部初始化 |
?語義明確性? | 狀態來源混雜難維護 | 強制內部狀態隔離 |
?兼容性? | 支持V1組件 | 僅限@ComponentV2 組件 |
(3)使用規范與限制
強制規則?
必須與@ComponentV2配合使用,在V1組件中無效
禁止與@Observed(V1)混用,需改用@ObservedV2
初始化要求?
@ComponentV2
struct MyComponent {@Local count: number = 0; ?// 合法(內部初始化)// @Local msg: string; ? ? // 非法(未初始化)
}
(4)高級應用場景
與@Param協作?
@Local用于組件內部狀態,@Param用于父組件傳參
典型模式:父組件通過@Param傳參,子組件用@Local維護衍生狀態
性能優化?
相比V1減少冗余狀態監聽,精準觸發UI更新
支持freezeWhenInactive凍結非活躍實例內存
@Param?
(1)基礎特性
作用定位?
專用于@ComponentV2組件接收父組件傳入的狀態數據,實現?單向數據流?
被裝飾變量?禁止組件內部直接修改?,需通過@Event回調通知父組件修改
數據同步機制?
父組件數據源變化時自動同步到子組件的@Param變量
對復雜類型(如類對象),子組件可修改其屬性并同步回父組件
(2)與V1裝飾器對比
?維度? | V1?@Prop | V2?@Param |
---|---|---|
?數據方向? | 嚴格單向(父→子) | 單向但支持屬性級修改 |
?類型支持? | 基礎類型+簡單對象 | 全類型(含Map/Set等) |
?初始化? | 必須父組件傳入 | 支持本地初始化(非必須) |
(3)核心規則
強制約束?
必須與@ComponentV2組件配合使用,V1組件中無效
變量類型需與父組件數據源嚴格一致
觀測能力?
基本類型?:整體賦值可觀測
對象類型?:僅觀測對象引用變化(屬性修改需配合@ObservedV2)
數組/Map?:API調用引發的變化可觀測(如push/set)
(4)高級用法
聯合@Once?
@Param @Once變量僅初始化時同步一次,后續父組件變化不更新子組件
@ComponentV2 struct Child {@Param @Once initValue: string; // 僅首次同步
}
聯合@Require?
強制要求父組件傳參,否則編譯報錯
@ComponentV2 struct Child {@Require @Param requiredData: string;
}
@Once?
(1)基礎特性
作用定位?
專用于實現變量?僅初始化時同步一次外部值?,后續數據源變化不更新子組件
必須與@Param聯合使用,不可單獨使用或搭配其他裝飾器
數據攔截機制?
僅攔截數據源變化,不影響@Param的觀測能力
允許子組件本地修改@Param變量的值(解除常規@Param不可修改限制)
(2)核心規則
?維度? | 說明 |
---|---|
?裝飾順序? | @Once @Param 或@Param @Once 均可,順序無影響 |
?使用范圍? | 僅限@ComponentV2 組件,V1組件無效 |
?類型支持? | 支持@Param 所有類型(基礎類型/對象/數組等) |
(3)典型應用場景
初始化后隔離父組件更新?
@ComponentV2 struct Child {@Param @Once fixedConfig: string; // 僅首次同步父組件配置
}
本地可修改的只讀參數?
@ComponentV2 struct Child {@Param @Once mutableValue: number; // 父組件初始化后可本地修改
}
(4)與相似裝飾器對比
裝飾器? | 數據同步機制 | 可修改性 | 典型場景 |
---|---|---|---|
@Param | 父→子持續同步 | 子組件不可修改 | 需響應父組件變化的參數 |
@Local | 完全內部狀態 | 可自由修改 | 純組件內部狀態管理 |
@Once | 僅首次同步 | 初始化后可修改 | 需初始值但隔離更新的配置 |
二、高級特性與規則
1. ?跨組件通信?
@Provider與@Consumer?
(1)基礎特性
作用定位?
實現跨組件層級的?雙向數據同步?,無需逐層傳遞參數
@Provider為數據提供方,@Consumer為數據消費方,通過aliasName建立綁定關系
版本要求?
僅支持@ComponentV2組件,V1組件使用會編譯報錯
從API version 12開始支持
(2)核心規則
?維度? | @Provider | @Consumer |
---|---|---|
?初始化? | 必須本地初始化 | 可本地初始化(未找到@Provider 時使用默認值) |
?數據同步? | 數據變化自動同步到所有綁定的@Consumer | 自動同步最近的@Provider 數據 |
?類型約束? | 需與@Consumer 類型嚴格一致 | 需與@Provider 類型嚴格一致 |
(3)關鍵機制
綁定規則?
通過?相同變量名?或?相同aliasName?建立綁定
若未指定aliasName,默認使用屬性名匹配
作用域?
@Consumer向上查找?最近父節點?的@Provider
支持一對多綁定(一個@Provider可對應多個@Consumer)
復雜類型支持?
支持對象/數組等復雜類型,需配合@ObservedV2實現屬性級觀測
@Event?
(1)基礎特性
作用定位?
專用于實現?父子組件事件回調?,簡化組件間通信邏輯
需與@ComponentV2配合使用,V1組件無效
核心能力?
支持定義?帶參數的回調函數?,參數類型需顯式聲明
通過事件觸發父組件狀態更新,實現數據反向傳遞
(2)核心規則
維度? | 說明 |
---|---|
?裝飾對象? | 僅能修飾回調函數(不能修飾變量) |
?參數傳遞? | 支持多參數傳遞,需在聲明時指定類型(如(count: number, text: string) => void ) |
?綁定方式? | 父組件通過屬性傳遞回調函數,子組件通過@Event 接收 |
?命名規范? | 建議以on 前綴命名(如onCountChange ) |
(3)典型應用場景
子組件通知父組件?
// 父組件
handleUpdate = (newVal: number) => {?this.parentVal = newVal;?
}
ChildComponent({ onUpdate: this.handleUpdate })// 子組件
@Event onUpdate: (val: number) => void;
Button('+1').onClick(() => this.onUpdate(100))
雙向數據流實現?(配合@Param)
// 父組件
@Local count: number = 0;
ChildComponent({?count: this.count,?onCountChange: (v) => { this.count = v }?
})// 子組件
@Param count: number;
@Event onCountChange: (v: number) => void;
(4)與相似裝飾器對比
?裝飾器? | 數據流向 | 典型場景 |
---|---|---|
@Param | 父→子單向 | 父組件傳遞只讀數據 |
@Link | 父子雙向 | 需雙向綁定的狀態 |
@Event | 子→父單向 | 子組件觸發父組件邏輯 |
2. ?性能優化裝飾器?
@Computed?
(1)基礎特性
作用定位?
用于定義?計算屬性?,優化重復計算的性能開銷
依賴的狀態變量變化時自動觸發重新計算,但僅計算一次
版本要求?
僅支持@ComponentV2組件,V1組件無效
(2)核心規則
維度? | 說明 |
---|---|
?裝飾對象? | 只能修飾getter 方法,不能修飾普通屬性或方法 |
?計算時機? | 首次訪問時計算,依賴項變化后再次訪問時重新計算 |
?數據流? | 單向只讀,不可用于雙向綁定 |
?依賴限制? | 計算函數內不能修改其他狀態變量 |
(3)典型應用場景
復雜計算邏輯封裝?
@Computed get fullName() {return `${this.firstName} ${this.lastName}`; // 合并姓名
}
性能敏感場景優化?
@Computed get filteredList() {return this.rawList.filter(item => item.score > 60); // 避免重復過濾
}
(4)與相似裝飾器對比
裝飾器? | 數據特性 | 典型場景 |
---|---|---|
@Local | 可讀寫狀態 | 組件內部狀態管理 |
@Param | 父→子單向 | 父組件傳遞只讀數據 |
@Computed | 只讀計算值 | 依賴多項數據的派生狀態 |
@Monitor?
(1)基礎特性
作用定位?
增強狀態變量變化的監聽能力,支持深度監聽嵌套對象/數組等復雜數據結構
對標V1的@Watch,但功能更強大,支持變化前后值對比
版本要求?
僅支持@ComponentV2組件,API version 12起支持
(2)核心規則
維度? | 說明 |
---|---|
?監聽對象? | 需被@Local 、@Param 、@Provider 、@Consumer 或@Computed 修飾的變量 |
?變化檢測? | 使用嚴格相等(=== )比較,若不等則觸發回調 |
?回調時機? | 避免在回調中修改其他狀態變量,可能引發循環更新 |
?深度監聽? | 需配合@ObservedV2 和@Trace 實現嵌套類/對象數組的屬性級監聽 |
(3)典型應用場景
基礎監聽?
@Local @Monitor('onCountChange') count: number = 0;
onCountChange(newVal: number, oldVal: number) {console.log(`值從${oldVal}變為${newVal}`);
}
復雜類型監聽?
@ObservedV2 class NestedClass {@Trace value: string = '';
}
@Local @Monitor('onNestedChange') obj: NestedClass = new NestedClass();
(4)與@Watch對比
特性? | @Watch ?(V1) | @Monitor ?(V2) |
---|---|---|
監聽范圍 | 僅一級屬性 | 支持深度嵌套屬性 |
回調參數 | 無變化前后值 | 提供newVal/oldVal |
多屬性監聽 | 需單獨聲明 | 單裝飾器可監聽多屬性 |
3. ?關鍵約束規則?
依賴關系?:
@ObservedV2必須搭配@Trace使用,單獨使用無效
@Once必須與@Param聯用,否則無法生效
更新機制?:
嵌套類中,需同時滿足@ObservedV2裝飾類和@Trace裝飾屬性才觸發更新
修改Map/Set等內置類型需通過UIUtils.getTarget()獲取原始對象
// 修改Map值示例
let rawMap = UIUtils.getTarget(this.stateMap);
rawMap.set('key', newValue); // 自動更新UI
三、認證高頻考點
1. ?裝飾器選型場景?
場景 | 推薦裝飾器 |
---|---|
組件內部狀態 | @Local (禁止外部初始化) |
父子組件數據同步 | @Param (外部輸入)+?@Event (輸出) |
深層嵌套對象監聽 | @ObservedV2 ?+?@Trace |
2. ?典型錯誤排查?
UI不更新?:
檢查嵌套屬性是否遺漏@Trace裝飾
確認類是否被@ObservedV2裝飾
初始化報錯?:
@Local變量嘗試從外部傳入值
@Once未與@Param配合使用
3. ?性能優化考點?
避免在@Computed中執行耗時操作
優先使用@Trace替代@ObjectLink減少冗余渲染
附:V2 性能優勢對比?
場景 | V1 方案 | V2 方案 | 優化點 |
---|---|---|---|
嵌套對象監聽 | 需多層@ObjectLink | @Trace 單層精準更新 | 減少 50% 冗余代碼 |
數組更新 | 整體刷新 | 項級差分更新 | 降低渲染耗時 |