ArkTS 状态管理 V2 — @Local 装饰器详解
@Local 是 HarmonyOS ArkTS 状态管理 V2 体系中用于 组件内部状态管理 的核心装饰器。它使自定义组件拥有响应式的私有数据,能在数据变化时自动触发 UI 更新。华为开发者官网
一、@Local 的核心用途
@Local用来 声明组件内部状态变量;- 该状态是 私有的、封装的、只能在当前组件内部访问和修改;
- 当被
@Local装饰的属性发生变化时,使用它的 UI 会自动更新。华为开发者官网
与旧版 @State 最大的不同是: @Local 不能从组件外部初始化,它的值必须在组件内部直接设定。华为开发者官网
二、基本使用语法
在 @ComponentV2 组件中声明内部状态:
@ComponentV2
struct MyComponent {
@Local count: number = 0; // 内部状态,必须初始化
build() {
Column() {
Text(`计数:${this.count}`);
Button("增加").onClick(() => {
this.count++;
});
}
}
}
上例中,count 使用 @Local 进行声明,并初始化为 0; 当点击按钮修改 count 时,UI 会自动刷新,无需手动调用刷新逻辑。华为开发者官网
三、设计规则与行为规范
3.1 必须 本地初始化
被 @Local 修饰的变量 必须直接在声明时初始化,否则会 编译报错:
@Local title: string; // 编译错误:未初始化
正确写法是:
@Local title: string = "默认标题"; //
这是为了确保本地状态始终有确定的初始值,不依赖外部传入。华为开发者官网
3.2 作用域严格限定
@Local状态 不能从父组件或外部传入;- 只能在当前组件内部使用;
- 子组件也 无法直接访问父组件的
@Local状态。
如果需要跨组件通信应使用如 @Param、@Provider/@Consumer 或全局状态。华为开发者官网
四、可观测的数据类型与行为
| 数据类型 | 是否触发 UI 更新 |
|---|---|
| 基本类型(number/string/boolean) | 支持 |
| Array / Map / Set / Date(集合类型) | 支持 API 级变化监听 |
| 自定义 Class/对象 | 不支持深度属性监听(只能整体重赋值触发) |
说明:
- 对于集合类型,只有通过集合 API 方法(如
push()、set()等)改变数据时才会触发 UI 更新; - 对于复杂对象,如果你只改对象内部某个字段 不会触发更新,需要整体替换对象变量本身。IT营社区
五、常见使用场景
5.1 简单内部状态
最典型场景是某些局部状态,例如计数器、切换开关、局部 UI 状态:
@ComponentV2
struct ToggleButton {
@Local isOn: boolean = false;
build() {
Button(this.isOn ? "开" : "关")
.onClick(() => this.isOn = !this.isOn);
}
}
当 isOn 切换时,该按钮的文本会自动更新。华为开发者官网
5.2 集合类型观测
@ComponentV2
struct TagList {
@Local tags: string[] = [];
build() {
Column() {
ForEach(this.tags, (tag) => Text(tag));
Button("添加标签")
.onClick(() => this.tags.push("新标签"));
}
}
}
因为 tags 是数组,push 会触发自动更新 UI。IT营社区
六、常见坑与注意事项
6.1 嵌套对象属性更新不触发 UI
class User { name: string = ""; }
@ComponentV2
struct Profile {
@Local user: User = new User();
build() {
// 下一行仅改属性,不触发更新
this.user.name = "Alice";
}
}
因为 @Local 不支持深度属性监听。 如需监听对象内部变化,应整体替换对象本身或使用 @ObservedV2 + @Trace。IT营社区
6.2 错误外部传值
// 父组件中尝试传值 ❌
<ChildComponent initialCount={5} />
这是错误做法。若需要从父组件传值,应使用 @Param。华为开发者官网
七、与 V1 @State 的对比
| 特性 | @Local(V2) | @State(V1) |
|---|---|---|
| 是否允许外部初始化 | 不允许 | 允许 |
| 是否可用于跨组件通信 | 不支持 | 部分支持 |
| 是否与 V2 组件状态体系兼容 | 强兼容 | 次优 |
| 状态封装性 | ⭐⭐⭐⭐(强) | ⭐(较弱) |
@Local 通过限制初始化和访问域,让组件内部状态更封闭、更纯粹,避免外部对内部状态的意外干预。华为开发者官网
八、最佳实践建议
推荐使用场景
- 组件内部 UI 状态,例如:开关状态、计数器、是否展开等;
- 组件短生命周期状态,不需要传出或共享。
优化建议
- 对于深层数据结构建议使用
@ObservedV2 + @Trace; - 对于需要父组件初始化状态值的场景,配合
@Param与@Once使用; - 避免将复杂状态嵌套在单个
@Local对象中。IT营社区
九、总结
@Local 是 ArkTS 状态管理 V2 体系中 专为组件内部状态设计的装饰器,它:
- 强制本地初始化,不允许外部直接赋值;
- 能对基础类型和集合类型进行响应式监听;
- 通过自动触发渲染实现更简单的 UI 更新逻辑;
- 与
@ComponentV2搭配,是构建现代 HarmonyOS 组件的基础。华为开发者官网