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

自定义组件的基本结构

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. @Component 和 struct 两者配对使用
  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 对指定事件的订阅。
相关推荐
行者-全栈开发10 小时前
【鸿蒙心迹】三方库移植(二)——CMake 交叉编译与符号冲突排查实录(HarmonyOS 7.x)
harmonyos·cmake·交叉编译·三方库移植·ohos·符号冲突
梦想不只是梦与想11 小时前
鸿蒙三方库源码调试
harmonyos·断点调试·三方源码调试
用户1179104883313 小时前
AI输出满屏井号星号?hmharness把Markdown渲染成终端表格 GitHub:swsgbl/hmharness
ai编程·harmonyos
了一12315 小时前
鸿蒙ArkWeb 长截图(滚动截图)技术方案总结
harmonyos
熊猫钓鱼>_>16 小时前
平行视界兼容模式与魔法变量配置避坑【鸿蒙心迹】
运维·服务器·开发语言·笔记·华为·harmonyos·openharmony
罗四强17 小时前
第2篇:环境搭建:DevEco Studio 安装 + 第一个 Hello World
harmonyos·鸿蒙·鸿蒙系统
用户1179104883318 小时前
AI终端里复制不了代码?hmharness把鼠标还给终端 GitHub:swsgbl/hmharness
ai编程·harmonyos
贾伟康20 小时前
HarmonyOS 端侧智能体长对话压缩:摘要版本、证据索引与安全回退
harmonyos·arkts·状态恢复·上下文压缩·端侧智能体
NJPJI_Yang21 小时前
鸿蒙操作系统小艺 Skill 开发实战:让应用被 HarmonyOS 7 一句话召唤
pytorch·深度学习·harmonyos
redtank20001 天前
纯血鸿蒙学习效率三件套实测:背单词艾宾浩斯曲线、时间记录与睡眠辅助
学习·华为·harmonyos