ArkTS 状态管理 V2 — @Once 装饰器详解

35 阅读3分钟

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 标记时:

  1. 子组件首次创建时,onceParam 会从父组件传入的值 进行初始化
  2. 父组件在之后的生命周期里即便修改对应的状态值,子组件中的 onceParam 仍然保持首次的值不变
  3. 这种行为类似 “一次性默认值初始化 + 局部固化配置”。华为开发者官网

三、典型使用场景与代码示例

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 联合使用,实现父组件传入参数 只初始化一次、之后不再更新
  • 适用于组件 “静态配置值、初始值固定” 等场景;
  • 增强了组件参数语义化、可控性和代码可读性华为开发者官网