首页 > 其他分享 >鸿蒙开发 - 自定义组件 和 组件通信的方法

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

时间:2025-01-14 11:10:07浏览次数:1  
标签:自定义 鸿蒙 text Component build 组件 string struct

自定义组件的基本结构

@Entry
@Component
struct MyComponent {
  build(){
     // ...
  }
}
  • build()函数

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

build() {
  Column() {
    Text('测试')
    Button('点击')
  }
}
  • struct 关键字

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

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

struct MyComponent {
}
  • @Component 装饰器

@Component 用来声明一个组件

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

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

@Entry
@Component
struct MyComponent {
  build() {
  }
}

组件通信

父子间单向传递 @Prop

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

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

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

  • 父组件
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 装饰器进行修饰变量

@Component
export default struct Child {
  @Prop text: string = ''

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

按钮点击前:

img.png

按钮点击后:

img_1.png

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

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


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

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

// 子组件

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

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

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

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

img_2.png

子组件调用父组件的方法

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

  • 父组件

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

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 函数,调用即可

@Component
export default struct Child {
  parentClick?: () => void

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

初始化效果图:

img_3.png

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

img_4.png

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

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

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

@Provide text: string = '123'

后代组件使用 @Consume 接收

@Consume text: string

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

eventHub 事件总线

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

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

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

@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 对指定事件的订阅。

标签:自定义,鸿蒙,text,Component,build,组件,string,struct
From: https://www.cnblogs.com/naturl/p/18668909

相关文章

  • 用DevEco Studio性能分析工具 高效解决鸿蒙原生应用内存问题
    在鸿蒙原生应用开发过程中,可能由于种种原因导致应用内存未被正常地使用或者归还至操作系统,从而引发内存异常占用、内存泄漏等问题,最终导致应用卡顿甚至崩溃,严重影响用户体验。为了帮助鸿蒙应用开发者高效定位并解决内存问题、提升应用稳定性与体验,华为在DevEcoStudio上提供了专属......
  • 界面控件 DevExpress v24.2 新版亮点 - 自定义和扩展 AI 驱动的扩展
    DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpressDashboardeXpressApp框架、适用于VisualStudio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress今年第一个重要版本v23.1正式发布,该版本拥有众多新产品和数十个具有高影响力......
  • Vue.js组件开发-实现图片裁剪
    在Vue.js中开发一个图片裁剪组件,可以使用cropperjs库,它是一个功能强大的JavaScript库,专门用于图片裁剪。在Vue项目中,可以通过vue-cropperjs这个Vue包装器来更方便地使用cropperjs。步骤:1.安装依赖首先,需要安装cropperjs和vue-cropperjs:npminstallcropperjsvue-cropperj......
  • Winform自定义控件与案例 - 打造炫酷的自定义开关按钮控件
    文章目录1、控件效果2、开关控件需求说明3、案例实现1、属性扩展代码实现2、控件外观绘制3、事件实现4、拓展方法4、案例演示5、总结1、控件效果2、开关控件需求说明在开发Winform应用程序时,拥有一个美观且功能强大的UI控件库是非常重要的。本文将详细介绍如......
  • Django Admin 自定义操作封装
    1.为什么需要封装?在Django开发中,我们经常需要在Admin界面添加自定义操作按钮,以便管理员执行特定的任务。通过封装,我们可以:减少重复代码统一管理自定义操作的逻辑提高代码的可维护性和可扩展性©ivwdcwso(ID:u012172506)2.CustomActionMixin的实现让我们看看C......
  • 【Python】深入解析Python的上下文管理器与资源管理:实现自定义的`with`语句
    《PythonOpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界在现代编程中,资源管理的高效与安全性至关重要。Python通过上下文管理器与with语句为开发者提供了一种简洁而强大的资源管理机制。上下文管理器......
  • 鸿蒙 NEXT 开发中,普通对象跨线程如何传递
    大家好,我是V哥,在鸿蒙HarmonyOSNEXT开发中,跨线程对象传递可以通过拷贝形式实现,确保两个线程的对象内容一致,但各自指向线程的隔离内存区间。以下是使用SharedArrayBuffer实现跨线程共享内存的完整案例代码,包括详细解释,整理的学习笔记,分享给大家。关注威哥不迷路,学习鸿蒙就很酷。......
  • Qt 自定义控件(Qt绘图)
    一、QPaintEvent绘图事件1、QPaintEvent是Qt框架中一个重要的事件类,专门用于处理绘图事件。2、当Qt视图组件需要重绘自己的一部分时,就会产生QPaintEvent事件。3、Qt视图组件重绘自己,通常发生在以下情况: (1)、窗口第一次显示时:当窗口或控件第一次出现在屏幕上时,系统会生......
  • Vue2-父子组件通信
    子组件<template><div><el-form><el-form-itemlabel="码值"><el-inputv-model="code"@input="sendFather"></el-input></el-form-item><el-form-itemlabe......
  • uniapp开发app、h5和微信小程序,8大好用的组件库推荐
    文章目录**1.uViewUI****2.TDesign(腾讯出品)****3.VarletUI****4.thor-ui****5.ColorUI****6.NutUI****7.VantWeapp****8.GraceUI****推荐选择****总结**在使用uni-app开发App、H5和微信小程序时,选择合适的组件库可以显著提升开发效率和用户体验。......