ArkTS 状态管理 V2 — @Once 装饰器详解
在 HarmonyOS ArkTS 状态管理 V2 体系中,@Once 是一个用于 控制子组件参数初始化行为 的装饰器。它与 @Param 搭配使用,可实现“只在组件初始化时接受父组件传入的值,之后即使父组件变化也不会同步更新”的效果。华为开发者官网
一、为什么要有 @Once
在组件开发中,经常会遇到这样一个场景:
我希望某个子组件属性 只在首次初始化时接收父组件传入的值,之后即便父组件中对应值发生改变——子组件也不再跟随变化。
这就正是 @Once 的设计初衷:
🔹 它能将参数约束成 只读且仅初始化一次; 🔹 父组件后续对该值的变更不会再触发子组件内部更新; 🔹 有助于实现诸如固定配置、静态初始值场景。华为开发者官网
二、核心定义与行为规范
2.1 装饰器本质
@Once是一个 属性装饰器;- 必须与
@Param一起使用,单独使用或与其他装饰器组合使用 是不允许的。华为开发者官网
也就是说:
// 错误示例:@Once 单独使用
@Once value: string = "";
改为:
// 正确写法:@Once + @Param
@Param @Once value: string = "";
2.2 工作机制
当一个参数使用了 @Param @Once 标记时:
- 子组件首次创建时,
onceParam会从父组件传入的值 进行初始化; - 父组件在之后的生命周期里即便修改对应的状态值,子组件中的
onceParam仍然保持首次的值不变; - 这种行为类似 “一次性默认值初始化 + 局部固化配置”。华为开发者官网
三、典型使用场景与代码示例
3.1 只初始化一次的参数
假设一个子组件需要在创建时接收父组件的标题,但之后标题改变子组件并不需要随之改变:
@ComponentV2
struct ChildComponent {
// 初始化一次并固定下来
@Param @Once initialText: string = "";
build() {
Text(`固定标题:${this.initialText}`);
}
}
@ComponentV2
struct ParentComponent {
@Local title: string = "第一次标题";
build() {
Column() {
Button("改变标题").onClick(() => {
this.title = "第二次标题";
});
ChildComponent({ initialText: this.title });
}
}
}
🔹 在上例中:
- 首次渲染时子组件的
initialText获取"第一次标题"; - 即使点击按钮将父组件
title修改为"第二次标题", - 子组件显示的
initialText仍然保持为首次值。华为开发者官网
3.2 与普通 @Param 的对比
| 场景维度 | 普通 @Param | @Param @Once |
|---|---|---|
| 数据流更新 | 父 → 子、持续同步 | 父 → 子、仅第一次 |
| 子组件呈现行为 | 始终跟随最新父组件状态 | 只跟随首次父组件状态 |
| 适用场景 | 子组件动态跟父组件值联动 | 子组件初始化固定值、静态配置 |
因此如果你希望子组件 每次接收最新值,应使用普通的 @Param;如果需要固定初始化值,则使用 @Param @Once。华为开发者官网
四、常见使用建议
4.1 典型适用场景
静态配置参数,例如主题色、初始状态等; 参数只在组件首次创建时需要使用,之后不再变化; 需要限定“初始化值不可更改”的业务逻辑。华为开发者官网
注意事项
不能单独使用 @Once,必须搭配 @Param; 与父组件状态无实时同步意图的参数不建议使用普通 @Param; 对于需要双向沟通的场景,应配合 @Event 使用。华为开发者官网
五、总结
@Once是 ArkTS V2 中用于控制组件参数初始化行为的装饰器;- 与
@Param联合使用,实现父组件传入参数 只初始化一次、之后不再更新; - 适用于组件 “静态配置值、初始值固定” 等场景;
- 它 增强了组件参数语义化、可控性和代码可读性。华为开发者官网