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