鸿蒙原生开发中自定义组件进阶——实现插槽(slot) 非常实用
·
我在学习鸿蒙开发前学习过许多前端技术,框架什么的,但是发现鸿蒙声明式开发范式中似乎没有插槽的类似东西,就查看了其他人的文章加上所学的知识研究了一下,本文章从头到尾讲述了声明式开发范式中的插槽,包括传入可点击的按钮什么的使用方法,如果还想知道更多的使用方式可以联系我。(第一次写文章,不好轻点喷)
一、基础知识
- 这里是给没接触过插槽的朋友们看的,插槽是前端一个常用的思想,用于向自定义组件中传入一个组件,使自定义组件的灵活性更高,代码复用率更高。
二、 鸿蒙声明式开发范式中实现插槽
以下是解释+示例,示例是一个自定义标题栏,也是非常实用。
- 先解释一下吧,自定义组件可以用@BuilderParam接收从父组件传下来的组件,并且使用(非常基础,有很多参考资料),接下来就是需要从子组件修改父组件的数据,@Link很好用,但是每次使用的时候都需要传一个数据到子组件才能进行修改,对于其他使用地方非常不友好,因为@Link传的数据是必须传入的,也就是说使用@Link的时候需要在同一个组件使用的地方都传入相关数据,非常的多余。但是有一个emitter就能解决该问题,emitter用法参考官方文档:
- 文档中心
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V13/js-apis-emitter-V13 - emitter的具体作用就是提供了在同一进程不同线程间,或同一进程同一线程内,发送和处理事件的能力,包括持续订阅事件、单次订阅事件、取消订阅事件,以及发送事件到事件队列的能力。(学过vue框架的会觉得非常眼熟)。接下来是示例+解释(预览请使用模拟器,预览器无法进行预览)。
1、基础样式
// 父组件样式
import { MyHeader } from '../component/MyHeader'
@Entry
@Component
struct TestPage {
@State message: string = 'Hello World'
@Builder
buttons() {
Button('点击改变数据', {type: ButtonType.Normal})
.backgroundColor(Color.Transparent)
.onClick(() => {
})
}
build(){
Column({space: 20}){
MyHeader({
Left_Message: '返回上一页',
right_box: this.buttons
})
Text(this.message)
}
.width('100%')
.height('100%')
}
}
// 子组件样式
@Builder
function rightBox() {
Text('默认组件')
}
@Component
export struct MyHeader{
@Prop Left_Message: string
@Prop isBack: boolean = true
@BuilderParam right_box: () => void = rightBox
build() {
Row(){
if(this.isBack){
Image($r('app.media.back'))
.height('50%')
.onClick(() => {
// router.back()
})
}
Text(this.Left_Message)
.fontSize(20)
Blank()
this.right_box()
}.width('100%')
.height(70)
.padding({
top: 17,
left: 10,
right: 10
})
.backgroundColor('#DFCEB4')
}
}
- 这个只是规定了自定义组件,然后传入一个区域可以用于接收从父组件传下来的组件,可以复制粘贴到编译器中查看效果,后续子组件修改父组件的数据效果将会依次添加。
2.添加emitter
- 在父组件传入子组件的buttons区域的按钮点击事件onClick中添加如下代码
let eventData: emitter.EventData = {
data: {
content: "message",
value: 'Hello ArkTS'
}
}
emitter.emit('changeData', eventData)
eventData是在规定发送事件的时候传递的参数,按照格式:键:值的方式传递(官方文档有),emitter.emit传递两个参数,changeData为eventId,eventData就是数据了。
相关使用方法也可以参考作者的另外一篇文章:
3.父组件添加持续订阅事件
- 然后在父组件中添加持续监听事件,如下:
aboutToAppear(): void {
emitter.on('changeData', (res) => {
let theData: myContent = res.data as myContent
this.message = theData.value
})
}
这样就可以在父组件中持续监听以changeData这个事件ID传入的了,emitter.on是一直监听,如果想监听一次可以使用emitter.once(详情请参考官方文档)。
大概效果如下:

然后你就能在不传入子组件的情况下,在子组件中修改父组件的参数,个人觉得很好用,初学者,勿喷,有什么问题也欢迎交流,如果你喜欢本文章,给个点赞关注评论吧,谢谢了。
更多推荐
所有评论(0)