鸿蒙开发 - 自定义组件 和 组件通信的方法

自定义组件的基本结构

typescript 复制代码
@Entry
@Component
struct MyComponent {
  build(){
     // ...
  }
}
  • build()函数

build()函数用于描述组件的UI界面,自定义组件必须定义build()函数

typescript 复制代码
build() {
  Column() {
    Text('测试')
    Button('点击')
  }
}
  • struct 关键字

strcut 用来声明数据结构 struct + 自定组件名 + { ... }

struct@Component 装饰后,必须要要有 build() 函数

typescript 复制代码
struct MyComponent {
}
  • @Component 装饰器

@Component 用来声明一个组件

  1. @Componentstruct 两者配对使用
  2. @Component只能装饰 struct 关键字声明的数据结构
typescript 复制代码
@Component 
struct MyComponent {
  build() {
  }
}
  • @Entry 装饰器

使用 @Entry 用于标记一个页面的入口点。当用户打开应用或导航路由的时候,展示的就是这个组件

typescript 复制代码
@Entry
@Component
struct MyComponent {
  build() {
  }
}

组件通信

父子间单向传递 @Prop

@Prop 单向传递数据:父组件数据变化,会通知子组件,但子组件数据变化,不会通知父组件

  1. 子组件深拷贝父组件传过来的数据,父组件发生数据变更,子组件会跟着变化
  2. 子组件也可以自己更新数据,但不会同步父组件数据

举例:父组件向子组件传递一个数据 text,默认值是 123,当点击按钮的时候,更新 text 的值为 456

  • 父组件
typescript 复制代码
import Child from './Child'

@Entry
@Component
struct Parent {
  @State text: string = '123'

  build() {
    Column() {
      Button(`按钮:${this.text}`)
        .onClick(() => {
          this.text = '456'
        })

      Child({ text: this.text })
    }
  }
}
  • 子组件

子组件使用 @Prop 装饰器进行修饰变量

typescript 复制代码
@Component
export default struct Child {
  @Prop text: string = ''

  build() {
    Row() {
      Text(`父组件传过来的内容:${this.text}`)
    }
  }
}

按钮点击前:

按钮点击后:

需要注意的是: 当父组件发生数据变更,子组件如果想跟着改变,就需要使用 @Prop 声明变量 @Prop text:string = ''。当然如果不需要跟着改变,也可以直接这么写 text:string = '',相当于将text的初始值传过去了,后续不会跟着变化

@Link 双向传递数据:父组件发生数据变化,会通知子组件,同时子组件数据变化,也通知父组件

使用 @Link,替换掉 @Prop,即 @Link text:string

需要注意的是: 使用 @Link 修饰的变量,不需要进行初始化,也就是不需要附一个初始值

typescript 复制代码
// 子组件

@Component
export default struct Child {
  @Link text: string

  build() {
    Column() {
      Text(`父组件传过来的内容:${this.text}`)

      Button('更改父组件传过来的数据')
        .onClick(() => {
          this.text = '789'
        })
    }
  }
}

当子组件点了更改数据的按钮,父组件也跟着发生了变化,效果图如下,

子组件调用父组件的方法

和传数据类似,只不过现在传递一个函数方法

  • 父组件

父组件定义一个方法 click, 传给子组件

typescript 复制代码
import Child from './Child'

@Entry
@Component
struct Parent {
  @State count: number = 0
  click: () => void = () => {
    this.count++
  }

  build() {
    Column() {
      Text(`点击次数:${this.count}`)

      Child({ parentClick: this.click })
    }
  }
}
  • 子组件

子组件声明父组件传过来的 parentClick 函数,调用即可

typescript 复制代码
@Component
export default struct Child {
  parentClick?: () => void

  build() {
    Column() {
      Button('点击')
        .onClick(() => {
          if (this.parentClick) {
            this.parentClick()
          }
        })
    }
  }
}

初始化效果图:

子组件调用父组件方法后:

跨组件双向通信(@Provide 和 @Consume)

使用@Provide@Consume 实现跨组件通信,这种方式是双向的,不管祖先组件还是后代组件发生数据变更,另外一方都会实时变化

祖先组件使用 @Provide 注入数据

typescript 复制代码
@Provide text: string = '123'

后代组件使用 @Consume 接收

typescript 复制代码
@Consume text: string

注意: @Consume 同样不需要初始化

eventHub 事件总线

eventHub 提供了事件中心,提供了监听事件和触发事件的能力,从而实现跨组件通信。(很接近vue的eventBus)

  • 祖先组件
typescript 复制代码
@Entry
@Component
struct Parent{
  build() {
    Column() {
      Button('发送')
        .onClick(() => {
          getContext(this).eventHub.emit('init', 2)
        })
    }
  }
}
  • 后代组件

后代组件中,先建立起监听事件,

typescript 复制代码
@Component
export default struct Grandchild {
  @State value: number = 1

  aboutToAppear(): void {
    getContext(this).eventHub.on('init', (data: number) => {
      this.handleMessage(data)
    })
  }

  handleMessage(value: number) {
    this.value = value
  }

  build() {
    Text(`接收到父组件发送的数据:${this.value}`)
  }
}
方法
  • on(event: string, callback: Function) 监听事件
  • emit(event: string, ...args: Object[]) 触发事件
  • off(event: string, callback?: Function) 取消订阅的指定事件
    • 传入 callback:取消指定的 callback 对指定事件的订阅,当该事件触发后,将不会再回调该callback。
    • 不传 callback:取消所有 callback 对指定事件的订阅。
相关推荐
程序猿阿伟44 分钟前
《AI赋能鸿蒙Next,打造极致沉浸感游戏》
人工智能·游戏·harmonyos
guo_zhen_qian2 小时前
HarmonyOS命令行工具
华为·harmonyos
HarmonyOS_SDK8 小时前
意图框架习惯推荐方案,为用户提供个性化内容分发
harmonyos
行十万里人生11 小时前
从 SQL 语句到数据库操作
数据库·sql·华为od·华为·oracle·华为云·harmonyos
对自己不够狠13 小时前
HarMonyOS使用Tab构建页签
前端·华为·harmonyos
peakmain913 小时前
HarmonyOS基本工具封装——拦截H5微信、支付宝支付和自定义H5全局拦截
harmonyos
鸿蒙自习室15 小时前
鸿蒙UI开发——基于onTouch事件实现表情选择胶囊
ui·华为·harmonyos
time_silence15 小时前
快速上手 HarmonyOS 应用开发
华为·harmonyos
程序猿阿伟16 小时前
《AI赋能鸿蒙Next,开启智能关卡设计新时代》
人工智能·harmonyos·关卡设计