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