一、概述
@Once装饰器用于实现变量仅在初始化时同步一次外部传入值,后续数据源更改时不会将修改同步给子组件。其必须搭配@Param使用,且不影响@Param的观测能力,仅拦截数据源变化,与@Param装饰变量的先后顺序不影响实际功能,并且在搭配使用时可在本地修改@Param变量的值。
二、装饰器使用规则说明
(一)@Once变量装饰器
- 装饰器参数:无。
- 使用条件:无法单独使用,必须配合@Param装饰器使用。
(二)限制条件
- @Once只能用在@ComponentV2装饰的自定义组件中且仅能与@Param搭配使用。例如:
@ComponentV2
struct CompA {
@Param @Once onceParam: string = "onceParam"; // 正确用法
@Once onceStr: string = "Once"; // 错误用法,@Once无法单独使用
@Local @Once onceLocal: string = "onceLocal"; // 错误用法,@Once不能与@Local一起使用
}
@Component
struct Index {
@Once @Param onceParam: string = "onceParam"; // 错误用法
}
- @Once与@Param的先后顺序无关,如@ComponentV2结构中写成@Param @Once或@Once @Param均可。
@ComponentV2
struct CompA {
@Param @Once param1: number;
@Once @Param param2: number;
}
三、使用场景
(一)变量仅初始化同步一次
适用于期望变量仅在初始化时同步数据源一次,之后不再继续同步变化的场景。例如:
@ComponentV2
struct CompA {
@Param @Once onceParam: string = '';
build() {
Column() {
Text(`onceParam: ${this.onceParam}`)
}
}
}
@Entry
@ComponentV2
struct CompB {
@Local message: string = "Hello World";
build() {
Column() {
Text(`Parent message: ${this.message}`)
Button("change message")
.onClick(() => {
this.message = "Hello Tomorrow";
})
CompA({ onceParam: this.message })
}
}
}
(二)本地修改@Param变量
当@Once搭配@Param使用时,可解除@Param无法在本地修改的限制,且修改能触发UI刷新,此时相当于@Local,但@Param @Once能接受外部传入初始化。例如:
@ObservedV2
class Info {
@Trace name: string;
constructor(name: string ) {
this.name = name;
}
}
@ComponentV2
struct Child {
@Param @Once onceParamNum: number = 0;
@Param @Once @Require onceParamInfo: Info;
build() {
Column() {
Text(`Child onceParamNum: ${this.onceParamNum}`)
Text(`Child onceParamInfo: ${this.onceParamInfo.name}`)
Button("changeOnceParamNum")
.onClick(() => {
this.onceParamNum++;
})
Button("changeParamInfo")
.onClick(() => {
this.onceParamInfo = new Info("Cindy");
})
}
}
}
@Entry
@ComponentV2
struct Index {
@Local localNum: number = 10;
@Local localInfo: Info = new Info("Tom");
build() {
Column() {
Text(`Parent localNum: ${this.localNum}`)
Text(`Parent localInfo: ${this.localInfo.name}`)
Button("changeLocalNum")
.onClick(() => {
this.localNum++;
})
Button("changeLocalInfo")
.onClick(() => {
this.localInfo = new Info("Cindy");
})
Child({
onceParamNum: this.localNum,
onceParamInfo: this.localInfo
})
}
}
}