系列文章目录
1.HarmonyOS | 状态管理(一) | @State装饰器
文章目录
前言
通过上一篇 HarmonyOS | 状态管理(一) | @State装饰器 的学习,大概了解状态管理的知识,本篇讲解 @Prop装饰器(父子单向同步)
一、@Prop装饰器是什么?
@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。
二、限制条件
@Prop装饰器不能在@Entry装饰的自定义组件中使用
三、使用场景
父组件@State到子组件@Prop简单数据类型同步
typescript
@Entry
@Component
struct ParentComponent {
@State countDownStartValue: number = 10;
build() {
Column(){
Text(`Grant ${this.countDownStartValue} nuggets to play.`)
Button(`+1 - Nuggets in New Game`).onClick(()=>{
this.countDownStartValue += 1;
}).margin(10)
Button(`-1 - Nuggets in New Game`).onClick(()=>{
this.countDownStartValue -= 1;
}).margin(10)
CountDownComponent({count:this.countDownStartValue,costOfOneAttempt:2})
}
}
}
@Component
struct CountDownComponent {
@Prop count:number;
costOfOneAttempt:number = 1;
build() {
Column() {
if (this.count > 0) {
Text(`You have ${this.count} Nuggets left`)
} else {
Text('Game over!')
}
// @Prop装饰的变量不会同步给父组件
Button(`Try again`).onClick(() => {
this.count -= this.costOfOneAttempt;
}).margin(10)
}
}
}
在上面的示例中:
-
CountDownComponent子组件首次创建时其@Prop装饰的count变量将从父组件@State装饰的countDownStartValue变量初始化;
-
按"+1"或"-1"按钮时,父组件的@State装饰的countDownStartValue值会变化,这将触发父组件重新渲染,在父组件重新渲染过程中会刷新使用countDownStartValue状态变量的UI组件并单向同步更新CountDownComponent子组件中的count值;
-
更新count状态变量值也会触发CountDownComponent的重新渲染,在重新渲染过程中,评估使用count状态变量的if语句条件(this.count > 0),并执行true分支中的使用count状态变量的UI组件相关描述来更新Text组件的UI显示;
-
当按下子组件CountDownComponent的"Try again"按钮时,其@Prop变量count将被更改,但是count值的更改不会影响父组件的countDownStartValue值;
-
父组件的countDownStartValue值会变化时,父组件的修改将覆盖掉子组件CountDownComponent中count本地的修改。
从父组件中的@State类对象属性到@Prop简单类型的同步
如果图书馆有一本图书和两位用户,每位用户都可以将图书标记为已读,此标记行为不会影响其它读者用户。从代码角度讲,对@Prop图书对象的本地更改不会同步给图书馆组件中的@State图书对象。
typescript
class Book {
public title: string;
public pages: number;
public readIt: boolean = false;
constructor(title: string, pages: number) {
this.title = title;
this.pages = pages;
}
}
@Component
struct ReaderComp {
@Prop title: string;
@Prop readIt: boolean;
build() {
Row() {
Text(this.title)
Text(`... ${this.readIt ? 'I have read' : 'I have not read it'}`)
.onClick(() => this.readIt = true)
}
}
}
@Entry
@Component
struct Library {
@State book: Book = new Book('100 secrets of C++', 765);
build() {
Column() {
ReaderComp({ title: this.book.title, readIt: this.book.readIt })
ReaderComp({ title: this.book.title, readIt: this.book.readIt })
}
}
}