鸿蒙Harmony开发:应用组件间的通信原理规范

前言

ETS(基于 TS 扩展的声明式开发范式)提供了强大的组件化能力,支持开发者高效的构建应用的 UI 界面,然而每一个组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互进行直接的引用,因此组件间的相互通信是非常重要的。

组件间通信原理

ETS 组件间通信是通过组合不同的装饰器来实现数据在各个组件之间的单向/双向传递。

相关装饰器介绍

装饰器名称 功能 特征
@State 所装饰变量的值发生变化时,将会调用所在组件的 build 方法进行 UI 刷新 支持装饰多种数据类型的变量(不允许 object 和 any);允许组件内存在多个被其装饰的变量;内部私有(@State 装饰的的变量是私有变量,只能在组件内访问);需要本地初始化(必须为所有 @State 装饰的变量分配初始值,否则可能导致框架行为未定义);创建自定义组件时支持通过状态变量名设置初始值
@Prop 具备 @State 的功能,装饰的变量能够和父组件中被 @State 装饰的变量建立单向数据绑定(只支持父组件传递数据至子组件),用于父组件向子组件传递数据 仅支持装饰简单类型(boolean,number,string)的变量;仅允许在组件内访问;允许组件内存在多个被其装饰的变量;装饰的所有变量必须使用其父组件提供的被 @State 装饰的变量进行初始化,不支持在组件内部进行初始化
@Link 具备 @State 的功能,装饰的变量可以和父组件中被 @State 装饰的变量建立双向数据绑定,用于父子组件间数据的双向传递 支持装饰多种数据类型的变量;仅在组件内访问; 双向通信(子组件对 @Link 装饰的变量的更改将同步修改父组件中被 @State 装饰的变量), 装饰的所有变量必须使用其父组件提供的被 @State 或 @Link 装饰的变量进行初始化,不支持在组件内部进行初始化;进行数据传递时需要通过'$'操作符将父组件的数据传给子组件
@Provide 具备 @State 的功能,可以和子/孙组件中被 @Consume 装饰的变量建立双向数据绑定 支持装饰多种数据类型的变量;该装饰器可以指定参数,用于给装饰的变量起别名,推荐使用 @Provide("alias")这种形式;需要指定初始值;一般和 @Consume 搭配使用;传递数据的方式比 @Link/@Prop 更简单,只要 @Consume 的参数值和 @Provide 的参数值一致就可以进行数据的双向传递,若两者都没有参数值,则它们装饰的变量名必须相同;@Provide/@Consume 可以代替 @State/@Link 传递数据,但是更适用于组件数据的跨层级传递的场景(例如组件 1 嵌套了组件 2,组件 2 嵌套组件 3,组件 3 嵌套了组件 4,要实现组件 1 和组件 4 之间的数据传递,使用 @Provide/@Consume 进行数据传递会更加方便)
@Consume 具备 @State 的功能,与 @Provide 搭配使用 不可设置默认值,必须和 @Provide 一起使用;使用 @Provide 和 @Consume 时避免循环引用导致死循环;使用了 @Consume 装饰器的组件上不能有 @Entry 装饰,否则程序会报错
@StorageLink 具备 @State 的功能,能与 AppStorage 建立双向数据绑定(AppStorage 是应用程序中的单例对象,与应用的生命周期相同,为应用程序范围内的可变状态属性提供中央存储) 支持装饰多种数据类型的变量; 被其装饰的变量即可以在组件内部初始化,也可以使用 AppStorage 中的值初始化;与 AppStorage 建立双向数据绑定,在 UI 组件中对 @StorageLink 装饰的变量所做的更改将同步到 AppStorage,并从 AppStorage 同步到任何其他绑定实例中;应用范围内的任意两个或多个组件都可以借助 AppStorage 进行数据传递
@Watch 用于监听被指定装饰器所装饰变量的变化 需要指定参数值,参数值是方法的名称;装饰的变量上必须有其他装饰器装饰;可以监听装饰器 @State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageLink 装饰的变量的变化(注意:监听 @StorageLink 装饰的变量时,@StorageLink 的参数值必须和其装饰的变量名一致)

组件间通信实现

父子组件通信

数据单向传递

使用 @State 和 @Prop 装饰器可以实现父组件向子组件单向传递数据。

  • 定义子组件 Child
@Component
struct Child {
    @Watch("listenChildCount") //当count变量值发生变化,会调用listenChildCount()
    @Prop
    count: number;
    build() {
        Column() {
                Text("子组件:" + this.count).fontSize(30)
                Button("reduce")
                    .fontSize(25)
                  

你可能感兴趣的:(HarmonyOS,OpenHarmony,鸿蒙,harmonyos,华为,前端,linux,鸿蒙,移动开发,组件)