fdfv232 发表于 2025-2-6 17:58:36

鸿蒙开发

自定义组件的基本结构

@Entry@Componentstruct MyComponent {build(){   // ...}}

[*]build()函数
build()函数用于描述组件的UI界面,自定义组件必须定义build()函数
build() {Column() {    Text('测试')    Button('点击')}}

[*]struct 关键字
strcut 用来声明数据结构 struct + 自定组件名 + { ... }
当 struct 被 @Component 装饰后,必须要要有 build() 函数
struct MyComponent {}

[*]@Component 装饰器
@Component 用来声明一个组件

[*]@Component 和 struct 两者配对使用
[*]@Component只能装饰 struct 关键字声明的数据结构
@Component struct MyComponent {build() {}}

[*]@Entry 装饰器
使用 @Entry 用于标记一个页面的入口点。当用户打开应用或导航路由的时候,展示的就是这个组件
@Entry@Componentstruct MyComponent {build() {}}组件通信

父子间单向传递 @Prop

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

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

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

[*]父组件
import Child from './Child'@Entry@Componentstruct Parent {@State text: string = '123'build() {    Column() {      Text(`我是父组件,文本内容:${this.text}`)      Button(`更新按钮`)      .onClick(() => {          this.text = '456'      })      Child({ text: this.text })      .margin({top: 50})    }    .width('100%')}}

[*]子组件
子组件使用 @Prop 装饰器进行修饰变量
@Componentexport default struct Child {@Prop text: string = ''build() {    Row() {      Text(`我是子组件,父组件传过来的内容:${this.text}`)    }}}效果如下:

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

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

使用 @Link,替换掉 @Prop,即 @Link text:string
需要注意的是: 使用 @Link 修饰的变量,不需要进行初始化,也就是不需要附一个初始值
// 子组件@Componentexport default struct Child {@Link text: stringbuild() {    Column() {      Text(`我是子组件,父组件传过来的内容:${this.text}`)      Button('更改父组件传过来的数据')      .onClick(() => {          this.text = '789'      })    }}}当子组件点了更改数据的按钮,父组件也跟着发生了变化,效果如下,

子组件调用父组件的方法

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

[*]父组件
父组件定义一个方法 click, 传给子组件
import Child from './Child'@Entry@Componentstruct Parent {@State count: number = 0click: () => void = () => {    this.count++}build() {    Column() {      Text(`我是父组件,记录点击次数:${this.count}`)      Child({ parentClick: this.click })    }}}

[*]子组件
子组件声明父组件传过来的 parentClick 函数,调用即可
@Componentexport default struct Child {parentClick?: () => voidbuild() {    Column() {      Button('我是子组件,点击')      .onClick(() => {          if (this.parentClick) {            this.parentClick()          }      })    }}}效果如下:

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

使用@Provide 和 @Consume 实现跨组件通信,这种方式是双向的,不管祖先组件还是后代组件发生数据变更,另外一方都会实时变化
祖先组件使用 @Provide 注入数据
@Provide text: string = '123'后代组件使用 @Consume 接收
@Consume text: string注意: @Consume 同样不需要初始化
eventHub 事件总线

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

[*]祖先组件
@Entry@Componentstruct Parent{build() {    Column() {      Button('发送')      .onClick(() => {          getContext(this).eventHub.emit('init', 2222)      })    }}}

[*]后代组件
后代组件中,先建立起监听事件,
@Componentexport default struct Grandchild {@State value: number = 1aboutToAppear(): 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 对指定事件的订阅。

页: [1]
查看完整版本: 鸿蒙开发