鸿蒙开发
自定义组件的基本结构@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]