状态管理
概述
HCompass 强制使用 V2 版本的状态管理 API,确保代码的一致性和可维护性。
V2 状态管理 API
@ObservedV2
用于标记可观察的类:
typescript
@ObservedV2
export class MyViewModel {
@Trace count: number = 0;
}@Trace
用于标记需要追踪的属性:
typescript
@ObservedV2
export class MyViewModel {
@Trace count: number = 0;
@Trace name: string = "";
@Trace isLoading: boolean = false;
}@Local
用于在组件中引用状态:
typescript
@Entry
@Component
struct MyPage {
@Local viewModel: MyViewModel = new MyViewModel();
build() {
Column() {
Text(`${this.viewModel.count}`);
Button("增加")
.onClick(() => {
this.viewModel.count++;
});
}
}
}状态管理层次
1. 组件级状态
仅在单个组件内使用的状态:
typescript
@Entry
@Component
struct MyPage {
@State count: number = 0;
build() {
Column() {
Text(`${this.count}`);
Button("增加")
.onClick(() => {
this.count++;
});
}
}
}2. ViewModel 状态
跨组件共享的状态,封装在 ViewModel 中:
typescript
@ObservedV2
export class MyViewModel {
@Trace count: number = 0;
increment(): void {
this.count++;
}
}
@Entry
@Component
struct MyPage {
@Local viewModel: MyViewModel = new MyViewModel();
build() {
Column() {
Text(`${this.viewModel.count}`);
Button("增加")
.onClick(() => {
this.viewModel.increment();
});
}
}
}3. 全局状态
跨功能包共享的状态,使用 AppStorageV2:
typescript
@ObservedV2
export class AppState {
@Trace isLoggedIn: boolean = false;
@Trace currentUser: UserInfo | null = null;
static getInstance(): AppState {
return AppStorageV2.getOrCreate("AppState", () => new AppState());
}
}
// 使用
const appState = AppState.getInstance();
appState.isLoggedIn = true;状态更新
直接赋值
typescript
@ObservedV2
export class MyViewModel {
@Trace count: number = 0;
increment(): void {
this.count++; // 直接赋值,自动触发 UI 更新
}
}对象更新
typescript
@ObservedV2
export class MyViewModel {
@Trace userInfo: UserInfo | null = null;
updateUserInfo(info: UserInfo): void {
// 创建新对象,而不是修改原对象
this.userInfo = { ...info };
}
}数组更新
typescript
@ObservedV2
export class MyViewModel {
@Trace dataList: Item[] = [];
addItem(item: Item): void {
// 创建新数组,而不是修改原数组
this.dataList = [...this.dataList, item];
}
removeItem(index: number): void {
this.dataList = this.dataList.filter((_, i) => i !== index);
}
}最佳实践
1. 使用 V2 API
强制使用 V2 版本的状态管理 API:
typescript
// 推荐
@ObservedV2
export class MyViewModel {
@Trace count: number = 0;
}
// 禁止
@Observed
export class MyViewModel {
@Track count: number = 0;
}2. 不可变性
始终创建新对象,而不是修改原对象:
typescript
// 推荐
this.userInfo = { ...this.userInfo, name: "新名字" };
// 禁止
this.userInfo.name = "新名字";3. 状态封装
将状态封装在 ViewModel 中,而不是直接在 View 中管理:
typescript
// 推荐
@ObservedV2
export class MyViewModel {
@Trace count: number = 0;
increment(): void {
this.count++;
}
}
// 不推荐
@Entry
@Component
struct MyPage {
@State count: number = 0;
build() {
Column() {
Button("增加")
.onClick(() => {
this.count++; // 业务逻辑不应该在 View 中
});
}
}
}4. 避免过度使用全局状态
只将真正需要跨功能包共享的状态放在全局:
typescript
// 推荐:全局状态
@ObservedV2
export class AppState {
@Trace isLoggedIn: boolean = false;
@Trace currentTheme: string = "light";
}
// 不推荐:局部状态放在全局
@ObservedV2
export class AppState {
@Trace userProfilePageScrollPosition: number = 0; // 这应该是局部状态
}性能优化
1. 避免频繁更新
typescript
// 不推荐
for (let i = 0; i < 1000; i++) {
this.count++; // 每次都会触发 UI 更新
}
// 推荐
let newCount = this.count;
for (let i = 0; i < 1000; i++) {
newCount++;
}
this.count = newCount; // 只触发一次 UI 更新2. 使用计算属性
typescript
@ObservedV2
export class MyViewModel {
@Trace firstName: string = "";
@Trace lastName: string = "";
get fullName(): string {
return `${this.firstName} ${this.lastName}`;
}
}注意事项
- V2 API:强制使用 V2 版本的状态管理 API
- 不可变性:始终创建新对象,不修改原对象
- 性能优化:避免频繁更新状态