鸿蒙HarmonyOS开发框架—学习ArkTS语言(状态管理 二)_harmoneyos arkts @state(1)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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;
})
}
}
}

@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;
})
// 父组件的修改会同步给子组件
Button(-1 - Nuggets in New Game).onClick(() => {
this.countDownStartValue -= 1;
})

CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2 })
}
}
}

在上面的示例中:

  1. CountDownComponent子组件首次创建时其@Prop装饰的count变量将从父组件@State装饰的countDownStartValue变量初始化;
  2. 按“+1”或“-1”按钮时,父组件的@State装饰的countDownStartValue值会变化,这将触发父组件重新渲染,在父组件重新渲染过程中会刷新使用countDownStartValue状态变量的UI组件并单向同步更新CountDownComponent子组件中的count值;
  3. 更新count状态变量值也会触发CountDownComponent的重新渲染,在重新渲染过程中,评估使用count状态变量的if语句条件(this.count > 0),并执行true分支中的使用count状态变量的UI组件相关描述来更新Text组件的UI显示;
  4. 当按下子组件CountDownComponent的“Try again”按钮时,其@Prop变量count将被更改,但是count值的更改不会影响父组件的countDownStartValue值;
  5. 父组件的countDownStartValue值会变化时,父组件的修改将覆盖掉子组件CountDownComponent中count本地的修改。
父组件@State数组项到子组件@Prop简单数据类型同步

父组件中@State如果装饰的数组,其数组项也可以初始化@Prop。以下示例中父组件Index中@State装饰的数组arr,将其数组项初始化子组件Child中@Prop装饰的value。

@Component
struct Child {
@Prop value: number;

build() {
Text(${this.value})
.fontSize(50)
.onClick(()=>{this.value++})
}
}

@Entry
@Component
struct Index {
@State arr: number[] = [1,2,3];

build() {
Row() {
Column() {
Child({value: this.arr[0]})
Child({value: this.arr[1]})
Child({value: this.arr[2]})

Divider().height(5)

ForEach(this.arr,
item => {
Child({value: item})
},
item => item.toString()
)
Text(‘replace entire arr’)
.fontSize(50)
.onClick(()=>{
// 两个数组都包含项“3”。
this.arr = this.arr[0] == 1 ? [3,4,5] : [1,2,3];
})
}
}
}
}

复制

初始渲染创建6个子组件实例,每个@Prop装饰的变量初始化都在本地拷贝了一份数组项。子组件onclick事件处理程序会更改局部变量值。

假设我们点击了多次,所有变量的本地取值都是“7”。

7
7
7

7
7
7

复制

单击replace entire arr后,屏幕将显示以下信息,为什么?

3
4
5

7
4
5

复制

  • 在子组件Child中做的所有的修改都不会同步回父组件Index组件,所以即使6个组件显示都为7,但在父组件Index中,this.arr保存的值依旧是[1,2,3]。
  • 点击replace entire arr,this.arr[0] == 1成立,将this.arr赋值为[3, 4, 5];
  • 因为this.arr[0]已更改,Child({value: this.arr[0]})组件将this.arr[0]更新同步到实例@Prop装饰的变量。Child({value: this.arr[1]})和Child({value: this.arr[2]})的情况也类似。
  • this.arr的更改触发ForEach更新,this.arr更新的前后都有数值为3的数组项:[3, 4, 5] 和[1, 2, 3]。根据diff机制,数组项“3”将被保留,删除“1”和“2”的数组项,添加为“4”和“5”的数组项。这就意味着,数组项“3”的组件不会重新生成,而是将其移动到第一位。所以“3”对应的组件不会更新,此时“3”对应的组件数值为“7”,ForEach最终的渲染结果是“7”,“4”,“5”。
从父组件中的@State类对象属性到@Prop简单类型的同步

如果图书馆有一本图书和两位用户,每位用户都可以将图书标记为已读,此标记行为不会影响其它读者用户。从代码角度讲,对@Prop图书对象的本地更改不会同步给图书馆组件中的@State图书对象。

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 })
}
}
}

复制

@Prop本地初始化不和父组件同步

为了支持@Component装饰的组件复用场景,@Prop支持本地初始化,这样可以让@Prop是否与父组件建立同步关系变得可选。当且仅当@Prop有本地初始化时,从父组件向子组件传递@Prop的数据源才是可选的。

下面的示例中,子组件包含两个@Prop变量:

  • @Prop customCounter没有本地初始化,所以需要父组件提供数据源去初始化@Prop,并当父组件的数据源变化时,@Prop也将被更新;
  • @Prop customCounter2有本地初始化,在这种情况下,@Prop依旧允许但非强制父组件同步数据源给@Prop。

@Component
struct MyComponent {
@Prop customCounter: number;
@Prop customCounter2: number = 5;

build() {
Column() {
Row() {
Text(From Main: ${this.customCounter}).width(90).height(40).fontColor(‘#FF0010’)
}

Row() {
Button(‘Click to change locally !’).width(480).height(60).margin({ top: 10 })
.onClick(() => {
this.customCounter2++
})
}.height(100).width(480)

Row() {
Text(Custom Local: ${this.customCounter2}).width(90).height(40).fontColor(‘#FF0010’)
}
}
}
}

@Entry
@Component
struct MainProgram {
@State mainCounter: number = 10;

build() {
Column() {
Row() {
Column() {
Button(‘Click to change number’).width(480).height(60).margin({ top: 10, bottom: 10 })
.onClick(() => {
this.mainCounter++
})
}
}

Row() {
Column()
// customCounter必须从父组件初始化,因为MyComponent的customCounter成员变量缺少本地初始化;此处,customCounter2可以不做初始化。
MyComponent({ customCounter: this.mainCounter })
// customCounter2也可以从父组件初始化,父组件初始化的值会覆盖子组件customCounter2的本地初始化的值
MyComponent({ customCounter: this.mainCounter, customCounter2: this.mainCounter })
}.width(‘40%’)
}
}
}


最后,为了能让大家更好的去学习提升鸿蒙 (Harmony OS) 开发技术,小编连夜整理了一份30个G纯血版学习资料(含视频电子书学习文档等)以及一份在Github上持续爆火霸榜的《纯血版华为鸿蒙 (Harmony OS)开发手册》(共计890页),希望对大家有所帮助。

纯血版鸿蒙 HarmonyOS 4.0 视频学习资料

需要以上视频学习资料小伙伴

请点击→纯血版全套鸿蒙HarmonyOS学习资料


《纯血版华为鸿蒙 (Harmony OS)开发手册》

这份手册涵盖了当前鸿蒙 (Harmony OS) 开发技术必掌握的核心知识点

纯血版鸿蒙 (Harmony OS)开发手册部分精彩内容

HarmonyOS 概念:

  • 系统定义
  • 技术架构
  • 技术特性
  • 系统安全

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Ljq0UIZw-1715449813315)]
[外链图片转存中…(img-0SUT3XJK-1715449813315)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值