• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# \@Once:初始化同步一次
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @jiyujia926-->
5<!--Designer: @s10021109-->
6<!--Tester: @TerryTsao-->
7<!--Adviser: @zhang_yixin13-->
8
9想要实现仅从外部初始化一次且不接受后续同步变化的能力,可以使用\@Once装饰器搭配\@Param装饰器。
10
11阅读本文档前,请先阅读[\@Param](./arkts-new-param.md)。
12
13> **说明:**
14>
15> 从API version 12开始,在\@ComponentV2装饰的自定义组件中支持使用\@Once装饰器。
16>
17> 从API version 12开始,该装饰器支持在原子化服务中使用。
18
19## 概述
20
21\@Once装饰器在变量初始化时接受外部传入值进行初始化,后续数据源更改不会同步给子组件:
22
23- \@Once必须搭配\@Param使用,单独使用或搭配其他装饰器使用都是不允许的。
24- \@Once不影响\@Param的观测能力,仅针对数据源的变化做拦截。
25- \@Once与\@Param装饰变量的先后顺序不影响使用功能。
26- \@Once与\@Param搭配使用时,可以在本地修改\@Param变量的值。
27
28## 装饰器使用规则说明
29
30\@Once装饰器作为辅助装饰器,本身没有装饰类型要求和变量观察能力。
31
32| \@Once变量装饰器 | 说明                                      |
33| ---------------- | ----------------------------------------- |
34| 装饰器参数       | 无。                                      |
35| 使用条件         | 无法单独使用,必须配合\@Param装饰器使用。 |
36
37
38## 限制条件
39
40- \@Once仅在[\@ComponentV2](arkts-new-componentV2.md)装饰的自定义组件中与\@Param搭配使用。
41
42  ```ts
43  @ComponentV2
44  struct MyComponent {
45    @Param @Once onceParam: string = 'onceParam'; // 正确用法
46    @Once onceStr: string = 'Once'; // 错误用法,@Once无法单独使用
47    @Local @Once onceLocal: string = 'onceLocal'; // 错误用法,@Once不能与@Local一起使用
48  }
49  @Component
50  struct Index {
51    @Once @Param onceParam: string = 'onceParam'; // 错误用法
52  }
53  ```
54
55- \@Once与\@Param的先后顺序无关,可以写成\@Param \@Once也可以写成\@Once \@Param。
56
57  ```ts
58  @ComponentV2
59  struct MyComponent {
60    @Param @Once param1: number;
61    @Once @Param param2: number;
62  }
63  ```
64
65## 使用场景
66
67### 变量仅初始化同步一次
68
69\@Once用于期望变量仅初始化同步数据源一次,之后不再继续同步变化的场景。
70
71```ts
72@ComponentV2
73struct ChildComponent {
74  @Param @Once onceParam: string = '';
75  build() {
76  	Column() {
77  	  Text(`onceParam: ${this.onceParam}`)
78  	}
79  }
80}
81@Entry
82@ComponentV2
83struct MyComponent {
84  @Local message: string = 'Hello World';
85  build() {
86  	Column() {
87      Text(`Parent message: ${this.message}`)
88      Button('change message')
89        .onClick(() => {
90          this.message = 'Hello Tomorrow';
91        })
92      ChildComponent({ onceParam: this.message })
93  	}
94  }
95}
96```
97
98### 本地修改\@Param变量
99
100当\@Once与\@Param结合使用时,可以解除\@Param无法在本地修改的限制,并能够触发UI刷新。此时,使用\@Param和\@Once的效果类似于[\@Local](arkts-new-local.md),但\@Param和\@Once还能接收外部传入的初始值。
101
102```ts
103@ObservedV2
104class Info {
105  @Trace name: string;
106  constructor(name: string) {
107    this.name = name;
108  }
109}
110@ComponentV2
111struct Child {
112  @Param @Once onceParamNum: number = 0;
113  @Param @Once @Require onceParamInfo: Info;
114
115  build() {
116    Column() {
117      Text(`Child onceParamNum: ${this.onceParamNum}`)
118      Text(`Child onceParamInfo: ${this.onceParamInfo.name}`)
119      Button('changeOnceParamNum')
120        .onClick(() => {
121          this.onceParamNum++;
122        })
123      Button('changeParamInfo')
124        .onClick(() => {
125          this.onceParamInfo = new Info('Cindy');
126        })
127    }
128  }
129}
130@Entry
131@ComponentV2
132struct Index {
133  @Local localNum: number = 10;
134  @Local localInfo: Info = new Info('Tom');
135
136  build() {
137    Column() {
138      Text(`Parent localNum: ${this.localNum}`)
139      Text(`Parent localInfo: ${this.localInfo.name}`)
140      Button('changeLocalNum')
141        .onClick(() => {
142          this.localNum++;
143        })
144      Button('changeLocalInfo')
145        .onClick(() => {
146          this.localInfo = new Info('Cindy');
147        })
148      Child({
149        onceParamNum: this.localNum,
150        onceParamInfo: this.localInfo
151      })
152    }
153  }
154}
155```
156
157