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