【HarmonyOS】HarmonyOS NEXT学习日记:八、组件通信

news2024/11/15 11:57:21

【HarmonyOS】HarmonyOS NEXT学习日记:八、组件通信

通过前面的学习我们基本上掌握了如何封装组件,但是实际使用过程中组件之间的状态需要互相之间关联通讯,涉及到父子组件,后代组件之间的相互通信。
请添加图片描述

@State装饰器:组件内状态

这是最常用的一种装饰器,它装饰的变量不与父组件中任何类型的变量同步。
@State装饰的变量,与声明式范式中的其他被装饰变量一样,是私有的,只能从组件内部访问,在声明时必须指定其类型和本地初始化。初始化也可选择使用命名参数机制从父组件完成初始化。

@State装饰的变量拥有以下特点:

@State装饰的变量与子组件中的@Prop装饰变量之间建立单向数据同步,与@Link、@ObjectLink装饰变量之间建立双向数据同步。

@State装饰的变量生命周期与其所属自定义组件的生命周期相同。

@Prop装饰器:父子单向同步

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

代码示例:
我们在父组件定义一个title,将其传给子组件,子组件使用@Prop装饰的状态来接收
父组件:

// Index.ets
import text from '@ohos.graphics.text'
import { router } from '@kit.ArkUI';
import { MyListItem } from '../components/MyListItem'
@Entry
@Component
struct Index {
  @State title:string = 'parent'
  build() {
    Column(){
      Text('parentTitle:'+this.title)
        .fontSize(36)
        .fontColor(Color.Red)
      Text('childreTitle:').fontSize(36)
      MyListItem({title:this.title,onToDetail:()=>{
        router.pushUrl({url: 'pages/Second'})
      }})
    }
  }
}

子组件:

//MyListItem
@Component
export struct MyListItem {
  @Prop title: string
  onToDetail: Function = () => {
  }
  aboutToAppear(){
    this.title='children'
  }
  build() {
    Text(this.title).fontSize(50).onClick(() => {
      this.onToDetail()
    })
  }
}

在这里插入图片描述
可以看到,我们在子组件的aboutToAppear中将title修改为了’children‘,在子组件区域也确实展示为了children,但是父组件依然没有改变,是’parent‘。

那么我们修改父组件的title,子组件是什么表现呢?
修改父组件代码为:

// Index.ets
import text from '@ohos.graphics.text'
import { router } from '@kit.ArkUI';
import { MyListItem } from '../components/MyListItem'
@Entry
@Component
struct Index {
  @State title:string = 'parent'
  build() {
    Column(){
      Text('parentTitle:'+this.title)
        .fontSize(36)
        .fontColor(Color.Red)
        .onClick(()=>{
          this.title='parentChanged'
        })
      Text('childreTitle:').fontSize(36)
      MyListItem({title:this.title,onToDetail:()=>{
        router.pushUrl({url: 'pages/Second'})
      }})
    }
  }
}

页面初始化为
在这里插入图片描述

当我们点击文本触发新添加的点击事件修改父组件的title时:
在这里插入图片描述
子组件的@Prop title一起改变。

@Link装饰器:父子双向同步

子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。
我们还是写一个代码来看看效果

父组件:

// Index.ets
import text from '@ohos.graphics.text'
import { router } from '@kit.ArkUI';
import { MyListItem } from '../components/MyListItem'
@Entry
@Component
struct Index {
  @State title:string = 'parent'
  build() {
    Column(){
      Text('parentTitle:'+this.title)
        .fontSize(36)
        .fontColor(Color.Red)
        .onClick(()=>{
          this.title='parentChanged'
        })
      Text('childrenTitle:').fontSize(36)
      MyListItem({title:this.title})
    }
  }
}

子组件:

//MyListItem
@Component
export struct MyListItem {
  @Link title:string
  aboutToAppear(){
    console.log('title',this.title)
  }
  build() {
    Text(this.title).fontSize(50)
      .onClick(()=>{this.title='childrenChanged'})
  }
}

初始化页面
在这里插入图片描述
点击红色文字,修改父组件状态
在这里插入图片描述
点击最下方的黑色文字,修改子组件状态
在这里插入图片描述
至此,就实现了父子组件的状态同步通信。

问题

我们试着传递一个两层的对象看看
父组件:

// Index.ets
import text from '@ohos.graphics.text'
import { router } from '@kit.ArkUI';
import { MyListItem } from '../components/MyListItem'
import {childrenObj,title} from  '../components/MyListItem'
@Entry
@Component
struct Index {
  @State myTitle:title = {
    txt: 'parent'
  }
  @State obj:childrenObj = {
    title: this.myTitle
  }
  build() {
    Column(){
      Text('parentTitle:'+this.obj.title.txt)
        .fontSize(36)
        .fontColor(Color.Red)
        .onClick(()=>{
          console.log(this.obj.title.txt)
          this.obj.title.txt='parentChanged'
        })
      Text('childrenTitle:').fontSize(36)
      MyListItem({obj:this.obj})
    }
  }
}

子组件:

//MyListItem
interface childrenObj{
  title: title
}
interface title{
  txt: string
}
@Component
export struct MyListItem {
  @Link obj:childrenObj
  aboutToAppear(){
    console.log('title',this.obj.title.txt)
  }
  build() {
    Text(this.obj.title.txt).fontSize(50)
      .onClick(()=>{this.obj.title.txt='childrenChanged'})
  }
}
export {childrenObj,title}

在这里插入图片描述
!!!!!!!!!!!!无论如何修改obj.title.txt的值,页面都没有响应,这个状态对于页面来说,失去响应式了。
事实上在实际应用开发中,应用会根据开发需要,封装自己的数据模型。对于多层嵌套的情况,比如二维数组,或者数组项class,或者class的属性是class,他们的第二层的属性变化是无法观察到的。
如何解决我们稍后再说。!!!!!!!!!!!!!!

@Provide装饰器和@Consume装饰器:与后代组件双向同步

有的时候我们不仅仅需要父子之间传值,还需要后代组件和祖先组件之后跨层级传值,这种情况就需要用到 @Provide装饰器和@Consume装饰器。

@Provide和@Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递,@Provide和@Consume摆脱参数传递机制的束缚,实现跨层级传递。

其中@Provide装饰的变量是在祖先组件中,可以理解为被“提供”给后代的状态变量。@Consume装饰的变量是在后代组件中,去“消费(绑定)”祖先组件提供的变量。

我们在刚刚代码的基础上加一层组件Intermediate,让MyListItem组件变成Index下两层后代组件
Index:

// Index.ets
import text from '@ohos.graphics.text'
import { router } from '@kit.ArkUI';
import { Intermediate } from '../components/Intermediate'
@Entry
@Component
struct Index {
  @Provide title:string = 'parent'
  build() {
    Column(){
      Text('parentTitle:'+this.title)
        .fontSize(36)
        .fontColor(Color.Red)
        .onClick(()=>{
          this.title='parentChanged'
        })
      Text('childrenTitle:').fontSize(36)
      Intermediate()
    }
  }
}

Intermediate:

//Intermediate
import { MyListItem } from './MyListItem'

@Component
export struct Intermediate {
  build() {
    MyListItem()
  }
}

MyListItem:

//MyListItem
@Component
export struct MyListItem {
  @Consume title:string
  build() {
    Text(this.title).fontSize(50)
      .onClick(()=>{this.title='childrenChanged'})
  }
}

在这里插入图片描述
点击红色文字修改index状态
在这里插入图片描述
点击黑色文字修改后代组件状态
在这里插入图片描述
即完成了祖先组件和后代组件的双向状态绑定。

@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化

好的现在我们来解决一下刚刚发现的问题,当对象嵌套两层之后,状态失去了响应性。

// Index.ets
//MyListItem
@Observed
class ClassA {
  public c: string;

  constructor(c: string) {
    this.c = c;
  }
}
@Observed
class ClassB {
  public a: ClassA;
  public b: string;

  constructor(a: ClassA, b: string) {
    this.a = a;
    this.b = b;
  }
}
@Component
struct MyListItem {
  @ObjectLink a:ClassA
  build() {
    Text(this.a.c).fontSize(50)
      .onClick(()=>{
        this.a.c = 'ca';
      })
  }
}
@Entry
@Component
struct Index {
  @State b: ClassB = new ClassB(new ClassA('a'),'b');
  build() {
    Column(){
      MyListItem({a:this.b.a})
    }
    .width('100%')
    .onClick(()=>{
      this.b.a.c='pa'
    })
  }
}

在这里插入图片描述
点击父元素,给b.a.c赋值’pa’
在这里插入图片描述
点击子组件给a.c 赋值 ‘ca’在这里插入图片描述

$$内置组件双向同步

很多原生的组件我们要双向同步状态可以使用 , , ,运算符为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。

@Entry
@Component
struct TextInputExample {
  @State text: string = ''
  controller: TextInputController = new TextInputController()

  build() {
    Column({ space: 20 }) {
      Text(this.text)
      TextInput({ text: $$this.text, placeholder: 'input your word...', controller: this.controller })
        .placeholderColor(Color.Grey)
        .placeholderFont({ size: 14, weight: 400 })
        .caretColor(Color.Blue)
        .width(300)
    }.width('100%').height('100%').justifyContent(FlexAlign.Center)
  }
}

在这里插入图片描述
可以观察到输入框绑定值改变时,ui上的相同变量也一起刷新了。

@Watch装饰器:状态变量更改通知

@Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数。

@Component
struct TotalView {
  @Prop @Watch('onCountUpdated') count: number = 0;
  @State total: number = 0;
  // @Watch 回调
  onCountUpdated(propName: string): void {
    this.total += this.count;
  }

  build() {
    Text(`Total: ${this.total}`)
  }
}

@Entry
@Component
struct CountModifier {
  @State count: number = 0;

  build() {
    Column() {
      Button('add to basket')
        .onClick(() => {
          this.count++
        })
      TotalView({ count: this.count })
    }
  }
}

在这里插入图片描述

当子组件接收的count变化时会触发watch的回调onCountUpdated,在其中修改count状态的的值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1965659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Loader QML Type

文章目录 Loader QML Type描述属性(Properties)active : boolasynchronous : bool(异步)item : objectprogress : realsource : urlsourceComponent : Componentstatus : enumeration 信号(Signal Documentation&#…

四,搭建环境:表述层

四,搭建环境:表述层 文章目录 四,搭建环境:表述层设定 Web 工程web.xml 的配置编写配置 ContextLoaderListener配置 DispatcherServlet配置 CharacterEncodingFilter配置 HiddenHttpMethodFilter 配置 Spring MVC配置视图解析相关…

【JKI SMO】框架讲解(九)

本节内容将演示如何向SMO框架添加启动画面。 1.打开LabVIEW新建一个空白项目,并保存。 2.找到工具,打开SMO Editor。 3.新建一个SMO,选择SMO.UI.Splash。 4. 打开LabVIEW项目,可以看到项目里多了一个SystemSplash类。 打开Process…

c++11-lambda表达式,包装器function,bind

lambda表达式 lambda表达式在很多语言都是有的,c当然是有的,但是像C语言就没有这个。和很多语言相同c的lambda表达式都是为了简化代码,当我们需要传函数的时候我们就可以用lambda表达式写一个匿名函数。 书写格式: [capture-li…

【Log4j2】代码执行漏洞复现!

执行以下命令 启动命令 systemctl start dockercd vulhub/log4j/CVE-2021-44228docker-compose up -d # 访问网址 http://192.168.3.42:xxxx/solr/#/ 启动靶场环境并在浏览器访问!!! 先在自己搭建的DNSLOG平台上获取一个域名来监控我们注入的效果. 可以发现 /solr…

人工智能:所有144本SCI期刊都在这里(20本Top,4本On Hold)

本周投稿推荐 SCI&EI • 4区“水刊”,纯正刊(来稿即录) • CCF-B类,IEEE一区-Top(3天初审) EI • 各领域沾边均可(2天录用) 知网(CNKI)、谷歌学术 …

CS61C | lecture5

CS61C | lecture5 浮点数的表示 用一个小数点作为边界分隔整数部分和小数部分。 10.101 0 2 1 2 1 1 2 − 1 1 2 − 3 2.62 5 10 10.1010_{2}1\times2^11\times2^{-1}1\times2^{-3}2.625_{10} 10.10102​12112−112−32.62510​ Scientific Notation(Binary) 单精度…

.JPG图片,各种压缩率下的文件尺寸

测试结果 不改变图片幅面的情况下,cv2 jpg压缩算法: 默认quality是9550时,相应的图片尺寸是95的1/3 可用。25时,图片尺寸是1/4,仍可用。 2024/07/31 16:31 85,305 out_10.jpg 2024/07/31 16:31 …

不要怕,手把手带你做好小程序关键词优化

要想让小程序在众多同类中脱颖而出,吸引更多的用户,就必须进行有效的关键词优化。优化小程序关键词是提升小程序搜索排名和吸引目标用户的重要手段。以下是一些优化小程序关键词的具体步骤和策略: 一、关键词研究与选择 1.了解用户搜索习惯…

文件解析漏洞

IIS解析漏洞 在windows Server 2003安装iis 1.IIS6.X 1.1 目录解析 在网站下建立文件夹的名字为 .asp/.asa 的文件夹&#xff0c;其目录内的任何扩展名的文件都被IIS当作asp文件来解析并执行。 先创建一个1.asp文件夹 再创建一个1.txt 里面写 <%now()%> 2.1 畸形文件…

go test单元测试

go test Go语言中的测试依赖go test命令。 go test 命令是用来运行测试代码的工具。测试代码通常与要测试的代码放在同一个包中&#xff0c;并且测试文件通常以 _test.go 结尾。 go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内&#xff0c;所有以_tes…

中国星坤拨码开关系列:为电子设备控制的提供可靠连接

在电子设备日益复杂的今天&#xff0c;控制和设置的简便性成为了用户体验的关键。中国星坤推出的拨码开关以其直观的操作界面和高可靠性&#xff0c;正在引领电子设备控制的新纪元。本文将深入探讨星坤拨码开关的主要特性、应用场景及其在现代电子设备中的重要性。 直观的人机界…

连接器表面缺陷检测方案

连接器是一种用于连接电子设备或电路中不同部件之间的组件&#xff0c;通常用于传输电力、信号或数据。连接器的设计和类型各不相同&#xff0c;以适应不同设备和应用的需求。连接器用于连接电子设备之间的电线、电缆或电路板&#xff0c;实现信号传输和电力供应。连接器设计应…

教育杂志教育杂志社教育编辑部2024年第18期目录

卷首语 “浙”里启程&#xff0c;一路“黔”行 张国军; 1 特别关注 普通高中高质量发展的九大要素——以江苏省通州湾中学为例 徐新民; 4-9 专题策划 “四史”教育融入初中历史教育教学活动探索 陈清波; 10-12 新时代加强师德师风建设的实践与认识 吴东林; 13-…

免费获取Windows7专业版ISO镜像!附上详细安装教程

Windows7专业版系统相比家庭版功能更加完善和强大&#xff0c;支持加强的网络功能、高级备份功能、位置感知打印、加密文件系统等多项安全功能&#xff0c;还有Windows XP模式、脱机文件夹和移动中心等便捷功能&#xff0c;特别适合技术爱好者和中小企业用户安装使用。以下系统…

python之贪吃蛇

废话不多说&#xff0c;直接上代码&#xff08;确保已经安装 pygame&#xff09; import pygame import random# 基础设置 # 屏幕高度 SCREEN_HEIGHT 480 # 屏幕宽度 SCREEN_WIDTH 600 # 小方格大小 GRID_SIZE 20# 颜色设置 WHITE (255, 255, 255) BLACK (0, 0, 0) GREEN…

关于 Postman 这些你都知道吗?

Postman是接口测试工具&#xff0c;在做接口测试的时候&#xff0c;Postman相当于一个客户端&#xff0c;它可以模拟用户发起的各种http请求&#xff0c;将请求的数据发送到服务端&#xff0c;获取对应的结果&#xff0c;从而测试接口是否能够满足业务功能要求&#xff0c;很直…

# mongodb副本集,执行 rs.addArb(“172.18.30.110:27019“) 添加仲裁节点,客户端卡住,半天没有反应,解决方法

mongodb副本集&#xff0c;执行 rs.addArb(“172.18.30.110:27019”) 或者rs.add(“172.18.30.110:27019”, true) 添加仲裁节点&#xff0c;客户端卡住&#xff0c;半天没有反应&#xff0c;解决方法 1、可以退出主节点后&#xff0c;重新登录&#xff0c; # Ctrl C 或者&a…

高效学术翻译:2024五大工具助你攻克语言难题!

在学术研究领域&#xff0c;阅读和翻译外文文献是每位学者必备的基本功。然而&#xff0c;语言障碍往往成为制约学术发展的瓶颈。为了帮助广大研究人员提高学术翻译效率&#xff0c;本文将为您推荐五款实用的学术翻译工具 Foxit在线翻译&#xff1a;随时随地&#xff0c;轻松翻…