当前位置: 首页 > news >正文

【鸿蒙学习笔记】@Prop装饰器:父子单向同步

官方文档:@Prop装饰器:父子单向同步

[Q&A] @Prop装饰器作用

@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

[Q&A] @Prop装饰器特点

1・@Prop装饰器不能在@Entry装饰的自定义组件中使用。
2・@Prop装饰变量时会进行深拷贝,在拷贝的过程中除了基本类型、Map、Set、Date、Array外,都会丢失类型。

样例1:Date

@Component
struct DateComponent {@Prop childSelectedDate: Date = new Date('');build() {Column() {Row() {Button('child +1年').margin(5).width('30%').onClick(() => {this.childSelectedDate.setFullYear(this.childSelectedDate.getFullYear() + 1)})Button('child +1月').margin(5).width('30%').onClick(() => {this.childSelectedDate.setMonth(this.childSelectedDate.getMonth() + 1)})Button('child +1天').margin(5).width('30%').onClick(() => {this.childSelectedDate.setDate(this.childSelectedDate.getDate() + 1)})}.width('100%')Button('child 重置日期').margin(10).width('100%').onClick(() => {this.childSelectedDate = new Date('2023-07-07')})DatePicker({start: new Date('1970-1-1'),end: new Date('2100-1-1'),selected: this.childSelectedDate})}}
}@Entry
@Component
struct SizeExample {@State parentSelectedDate: Date = new Date('2008-08-08');build() {Column() {Row() {Button('parent +1年').margin(5).width('30%').onClick(() => {this.parentSelectedDate.setFullYear(this.parentSelectedDate.getFullYear() + 1)})Button('parent +1月').margin(5).width('30%').onClick(() => {this.parentSelectedDate.setMonth(this.parentSelectedDate.getMonth() + 1)})Button('parent +1天').margin(5).width('30%').onClick(() => {this.parentSelectedDate.setDate(this.parentSelectedDate.getDate() + 1)})}.width('100%')Button('parent 重置日期').margin(10).width('100%').onClick(() => {this.parentSelectedDate = new Date('2023-07-07')})DatePicker({start: new Date('1970-1-1'),end: new Date('2100-1-1'),selected: this.parentSelectedDate})DateComponent({ childSelectedDate: this.parentSelectedDate })}}
}

在这里插入图片描述

样例2:父组件@State简单数据类型→子组件@Prop简单数据类型同步

@Component
struct CountDownComponent {@Prop count: number = 0;costOfOneAttempt: number = 1;build() {Row() {if (this.count > 0) {Text(`当前值为 ${this.count} .`).fontSize(20).margin(10).textAlign(TextAlign.Center)} else {Text('Game over!').fontSize(20).margin(10)}Button('子 -1').onClick(() => {this.count -= this.costOfOneAttempt;}).width("40%")}.width('100%')}
}@Entry
@Component
struct SizeExample {@State countDownStartValue: number = 10;build() {Column() {Row() {if (this.countDownStartValue > 0) {Text(`当前值为 ${this.countDownStartValue} .`).fontSize(20).margin(5).textAlign(TextAlign.Center)} else {Text('Game over!').fontSize(20).margin(10)}Button('父 +1 ').onClick(() => {this.countDownStartValue += 1;}).margin(5).width("20%")Button('父 -1 ').onClick(() => {this.countDownStartValue -= 1;}).margin(5).width("20%")}.width('100%')CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2 })}}
}

在这里插入图片描述

样例3:父组件@State数组项→子组件@Prop简单数据类型同步

@Component
struct Child {@Prop value: number = 0;build() {Text(`${this.value}`).fontSize(30).onClick(() => {this.value++})}
}@Entry
@Component
struct SizeExample {@State arr: number[] = [1, 2, 3];build() {Row() {Column() {Text(`当前值为 ${this.arr[0]},${this.arr[1]},${this.arr[2]}.`).fontSize(30).margin(10).textAlign(TextAlign.Center)Divider().height(10)Row() {Child({ value: this.arr[0] }).width('30%').align(Alignment.Center).backgroundColor(Color.Red)Child({ value: this.arr[1] }).width('30%').align(Alignment.Center).backgroundColor(Color.Green)Child({ value: this.arr[2] }).width('30%').align(Alignment.Center).backgroundColor(Color.Yellow)}.alignItems(VerticalAlign.Center)Divider().height(10)Row() {ForEach(this.arr, (item: number) => {Child({ value: item }).width('30%').align(Alignment.Center).backgroundColor(Color.Orange).border({ width: 1, style: BorderStyle.Dashed })}, (item: string) => item.toString())}.alignItems(VerticalAlign.Center)Divider().height(10)Text('重置').fontSize(30).backgroundColor(Color.Pink).width('50%').textAlign(TextAlign.Center).padding(10).onClick(() => {// 两个数组都包含项“3”。this.arr = this.arr[0] == 1 ? [3, 4, 5] : [1, 2, 3];})}}}
}

在这里插入图片描述

样例4:父组件@State类对象属性→@Prop简单类型的同步

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 book: Book = new Book("", 0);build() {Row() {Text(this.book.title).fontSize(20)Text(` 有 ${this.book.pages}! `).fontSize(20)Text(`${this.book.readIt ? " 我读了" : ' 我还没开始读'}`).fontSize(20).onClick(() => this.book.readIt = true).backgroundColor(Color.Pink)}}
}@Entry
@Component
struct SizeExample {@State book: Book = new Book('资治通鉴', 765);build() {Column() {ReaderComp({ book: this.book })ReaderComp({ book: this.book })}}
}

在这里插入图片描述

样例5:父组件@State数组项→@Prop class类型的同步

let nextId: number = 1;@Observed // @Prop在子组件装饰的状态变量和父组件的数据源是单向同步关系,需要使用@Observed装饰class Book,Book的属性将被观察。
class Book {public id: number;public title: string;public pages: number;public readIt: boolean = false;constructor(title: string, pages: number) {this.id = nextId++;this.title = title;this.pages = pages;}
}@Component
struct ReaderComp {@Prop book: Book = new Book("", 1);build() {Row() {Text(` ${this.book ? this.book.title : "未定义"}`).fontColor(Color.Red)Text(` 有 ${this.book ? this.book.pages : "未定义"}!`).fontColor(Color.Black)Text(` ${this.book ? (this.book.readIt ? "我已经读了" : '我还没读' ): "未定义"}`).fontColor(Color.Blue).onClick(() => this.book.readIt = true)}}
}@Entry
@Component
struct SizeExample {@State allBooks: Book[] = [new Book("资治通鉴", 100), new Book("史记", 100), new Book("论语", 100)];build() {Column() {Text('畅销书').width(312).height(40).fontSize(20).margin(12).fontColor('#e6000000')ReaderComp({ book: this.allBooks[2] }).backgroundColor('#0d000000').width(312).height(40).padding({ left: 20, top: 10 }).borderRadius(20).colorBlend('#e6000000')Divider()Text('已经购买的书').width(312).height(40).fontSize(20).margin(12).fontColor('#e6000000')ForEach(this.allBooks, (book: Book) => {ReaderComp({ book: book }).margin(12).width(312).height(40).padding({ left: 20, top: 10 }).backgroundColor('#0d000000').borderRadius(20)},(book: Book) => book.id.toString())Button('追加').width(312).height(40).margin(12).fontColor('#FFFFFF 90%').onClick(() => {this.allBooks.push(new Book("孟子", 100));})Button('移除第一本书').width(312).height(40).margin(12).fontColor('#FFFFFF 90%').onClick(() => {if (this.allBooks.length > 0){this.allBooks.shift();} else {console.log("length <= 0")}})Button("所有人都已经读了").width(312).height(40).margin(12).fontColor('#FFFFFF 90%').onClick(() => {this.allBooks.forEach((book) => book.readIt = true)})}}
}

在这里插入图片描述

样例6:@Prop本地初始化不和父组件同步

@Component
struct MyComponent {@Prop count1: number;@Prop count2: number = 5;build() {Column() {Row() {Text(`Parent: ${this.count1}`).fontColor('#ff6b6565').width('30%')Text(`Child: ${this.count2}`).fontColor('#ff6b6565').width('30%')Button('改变Child数值').width('30%').height(40).fontColor('#FFFFFF,90%').onClick(() => {this.count2++})}}}
}@Entry
@Component
struct SizeExample {@State mainCount: number = 10;build() {Column() {Row() {Column() {MyComponent({ count1: this.mainCount })Divider().height(10)MyComponent({ count1: this.mainCount, count2: this.mainCount })}}Divider().height(10)Column() {Button('改变Parent数值').width(288).height(40).width('100%').fontColor('#FFFFFF,90%').onClick(() => {this.mainCount++})}}}
}

在这里插入图片描述

样例7:@Prop嵌套场景

几个按钮跳的乱,需要消化

@Entry
@Component
struct SizeExample {@State book: Book = new Book('Book名字', new Title('Book标题'))build() {Column() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {Text(this.book.name).fontSize(16).margin(12).width(312).height(40).backgroundColor(Color.Green).borderRadius(20).textAlign(TextAlign.Center).fontColor('#e6000000').onClick(() => {this.book.name = '资治通鉴'})Text(this.book.title.title).fontSize(16).margin(12).width(312).height(40).backgroundColor(Color.Green).borderRadius(20).textAlign(TextAlign.Center).onClick(() => {this.book.title.title = "资治通鉴 标题"})ShowTitle({ title: this.book.title })Button('修改 Book 名字').width(312).height(40).margin(12).fontColor('#FFFFFF,90%').onClick(() => {this.book.name = "史记"})Button('修改 Book 标题').width(312).height(40).margin(12).fontColor('#FFFFFF,90%').onClick(() => {this.book.title.title = "史记 标题"})}}}
}@Component
struct ShowTitle {@Prop title: Title = new Title('');build() {Column() {Text(this.title.title).fontSize(16).margin(12).width(312).height(40).backgroundColor(Color.Orange).borderRadius(20).textAlign(TextAlign.Center).onClick(() => {this.title.title = '点击完毕'})}}
}// 以下是嵌套类对象的数据结构。
@Observed
class Title {public title: string;constructor(title: string) {this.title = title;}
}@Observed
class Book {public name: string;public title: Title;constructor(name: string, cla: Title) {this.name = name;this.title = cla;}
}

在这里插入图片描述

样例8:装饰Map类型变量

@Component
struct MapComponent {@Prop map: Map<number, string> = new Map([[0, "a"], [1, "b"], [3, "c"]])build() {Column() {ForEach(Array.from(this.map.entries()), (item: [number, string]) => {Row(){Text(`${item[0]}`).fontSize(30).margin(10)Text(`${item[1]}`).fontSize(30).margin(10)}Divider()})Button('初始化').margin(5).width('100%').onClick(() => {this.map = new Map([[0, "a"], [1, "b"], [3, "c"]])})Button('追加1组值').margin(5).width('100%').onClick(() => {this.map.set(4, "d")})Button('清除所有值').margin(5).width('100%').onClick(() => {this.map.clear()})Button('替换第1个值').margin(5).width('100%').onClick(() => {this.map.set(0, "aa")})Button('删除第1个值').margin(5).width('100%').onClick(() => {this.map.delete(0)})}}
}@Entry
@Component
struct SizeExample {@State message: Map<number, string> = new Map([[1, "a"], [2, "b"], [3, "c"]])build() {Row() {Column() {MapComponent({ map: this.message })}.width('100%').backgroundColor(Color.Green)}.height('100%').backgroundColor(Color.Pink)}
}

在这里插入图片描述

样例9:装饰Set类型变量

@Component
struct Child {@Prop message: Set<number> = new Set([0, 1, 2, 3, 4])build() {Column() {Row() {ForEach(Array.from(this.message.entries()), (item: [number, string]) => {Text(`${item[0]}`).fontSize(30).margin(10)})}Button('初始化Set').width('100%').onClick(() => {this.message = new Set([0, 1, 2, 3, 4])})Divider().height(10)Button('追加新值').width('100%').onClick(() => {this.message.add(5)})Divider().height(10)Button('清除所有值').width('100%').onClick(() => {this.message.clear()})Divider().height(10)Button('删除第一个值').width('100%').onClick(() => {this.message.delete(0)})}.width('100%')}
}@Entry
@Component
struct SizeExample {@State message: Set<number> = new Set([0, 1, 2, 3, 4])build() {Row() {Column() {Child({ message: this.message })}.width('100%')}.height('100%')}
}

在这里插入图片描述

样例10:Prop支持联合类型实例

class Animals {public name: string;constructor(name: string) {this.name = name;}
}@Component
struct Child {@Prop animal: Animals | undefined;build() {Column() {Text(`子  ${this.animal instanceof Animals ? this.animal.name : '未定义'}`).fontSize(20).backgroundColor(Color.Pink).width('100%').padding(5)Button('子 改为猫').width('100%').margin(5).onClick(() => {// 赋值为Animals的实例this.animal = new Animals("猫")})Button('子 改为 undefined').width('100%').margin(5).onClick(() => {// 赋值为undefinedthis.animal = undefined})}.width('100%')}
}@Entry
@Component
struct SizeExample {@State animal: Animals | undefined = new Animals("老虎");build() {Column() {Text(`父  ${this.animal instanceof Animals ? this.animal.name : '未定义'}`).fontSize(20).textAlign(TextAlign.Start).backgroundColor(Color.Yellow).width('100%').padding(5)Child({ animal: this.animal })Button('父 改为狗').width('100%').margin(5).onClick(() => {if (this.animal instanceof Animals) {this.animal.name = "狗"} else {console.info('num is undefined, cannot change property')}})Button('父 改为 undefined').width('100%').margin(5).onClick(() => {this.animal = undefined})}.backgroundColor(Color.Orange)}
}

在这里插入图片描述

相关文章:

  • spring boot读取yml配置注意点记录
  • [数据集][目标检测]围栏破损检测数据集VOC+YOLO格式1196张1类别
  • 封装stater时配置导入配置类提示功能
  • MacOS docker 安装与配置
  • 工具:颜色查询 / CMYK颜色查询RGB、HSL、HSV、XYZ的颜色值
  • 提升学生职务执行力的智慧校园学工管理策略
  • ubuntu中后台启动一个jar
  • 等保测评——云计算安全扩展(云计算关键技术)
  • amis中条件组合器condition-builder的使用 和 解析
  • 昇思MindSpore学习总结八——静态图加速
  • 【PHP】控制摄像头缩放监控画面大小,并保存可视画面为图片
  • IT设备监控模板:支持多种监控工具和平台的集成和整合
  • 微服务之服务保护策略【持续更新】
  • 初识单片机
  • 10计算机视觉—物体检测算法
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • Java精华积累:初学者都应该搞懂的问题
  • Java面向对象及其三大特征
  • js 实现textarea输入字数提示
  • js学习笔记
  • node学习系列之简单文件上传
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • webpack4 一点通
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 对象管理器(defineProperty)学习笔记
  • 复杂数据处理
  • 诡异!React stopPropagation失灵
  • 马上搞懂 GeoJSON
  • 面试遇到的一些题
  • 为视图添加丝滑的水波纹
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • !$boo在php中什么意思,php前戏
  • #QT(串口助手-界面)
  • (003)SlickEdit Unity的补全
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (C++17) std算法之执行策略 execution
  • (javascript)再说document.body.scrollTop的使用问题
  • (Python) SOAP Web Service (HTTP POST)
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转载)OpenStack Hacker养成指南
  • (轉貼) UML中文FAQ (OO) (UML)
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • ****Linux下Mysql的安装和配置
  • **python多态
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET开发人员必知的八个网站
  • .py文件应该怎样打开?
  • [2009][note]构成理想导体超材料的有源THz欺骗表面等离子激元开关——
  • [AIGC] SpringBoot的自动配置解析