【最新鸿蒙应用开发】——鸿蒙中的“Slot插槽”?@BuilderParam

构建函数-@BuilderParam 传递 UI

1. 引言

@BuilderParam 该装饰器用于声明任意UI描述的一个元素,类似slot占位符。 简而言之:就是自定义组件允许外部传递 UI

@Entry
@Component
struct Index {build() {Column({ space: 15 }) {SonCom() {// 直接传递进来(尾随闭包)Button('传入的结构').onClick(() => {AlertDialog.show({ message: '点了 Button' })})}}}
}

2. 单个@BuilderParam参数

首先来看看单个的情况:

使用尾随闭包的方式传入:

  • 组件内有且仅有一个使用 @BuilderParam 装饰的属性,即可使用尾随闭包
  • 内容直接在 {} 传入即可 注意:
  • 此场景下自定义组件不支持使用通用属性。
@Component
struct SonCom {// 由外部传入 UI@BuilderParam ContentBuilder: () => void = this.defaultBuilder
​// 设置默认 的 Builder,避免外部不传入@BuilderdefaultBuilder() {Text('默认的内容')}
​build() {Column() {this.ContentBuilder()}.width(300).height(200).border({ width: .5 })}
}
​
@Entry
@Component
struct Index {build() {Column({ space: 15 }) {SonCom() {// 直接传递进来Button('传入的结构').onClick(() => {AlertDialog.show({ message: '点了 Button' })})}}}
}

3. 多个@BuilderParam 参数

子组件有多个BuilderParam,必须通过参数的方式来传入

核心步骤:

  1. 自定义组件-定义: 添加多个 @BuilderParam ,并定义默认值

  2. 自定义组件-使用 通过参数的形式传入多个 Builder,比如这里的 SonCom({ titleBuilder: this.fTitleBuilder, contentBuilder: this.fContentBuilder })

需求:

  • 调整 卡片自定义组件,支持传入 UI PanelComp(){ // 此处传入 }

思路:

  • 直接大括号(尾随闭包)传入只需要设置一个BuilderParam即可:

@Component
struct PanelComp {title: string = ''more: string = ''@BuilderParam contentBuilder: () => void = this.defaultContentBuilderclickHandler: () => void = () => {AlertDialog.show({ message: '默认提示' })}
​@BuilderdefaultContentBuilder() {Text('默认的内容~')}
​build() {Column() {Row() {Text(this.title).layoutWeight(1).fontWeight(600)Row() {Text(this.more).fontSize(14).fontColor('#666666').onClick(() => {this.clickHandler()})Image('/common/day08-10/ic_public_arrow_right.svg').width(16).fillColor('#666666')}}.padding(10)
​Row() {this.contentBuilder()}.height(100)}.borderRadius(12).backgroundColor('#fff')}
}
​
@Entry
@Component
struct Index {build() {Column({ space: 15 }) {PanelComp({title: '评价(2000+)', more: '好评率98%', clickHandler() {console.log('传入的逻辑')}}) {Text('传入的标题').fontSize(20).fontWeight(600).fontColor(Color.White).backgroundColor(Color.Blue).padding(10)}
​Row({ space: 15 }) {PanelComp({ title: '推荐', more: '查看全部' }).layoutWeight(1)
​PanelComp({ title: '体验', more: '4 条测评' }).layoutWeight(1)}
​}.height('100%').padding(15).backgroundColor('#f5f5f5')}
}

4. 使用场景

这里简单举例两个关于我项目中适合使用的场景:


4.1. 任务列表页面

  • 自定义插槽

@Preview
@Component
struct HmToggleCard {title: string = "测试"@StatetoggleCard: boolean = true // 默认是展开的@BuilderParamCardContent: () => voidbuild() {Column() {Row() {Text(this.title).fontSize(16).fontColor($r('app.color.text_primary')).fontWeight(600)Image(this.toggleCard ? $r("app.media.ic_btn_cut") :$r("app.media.ic_btn_add")).width(24).height(24).onClick(() => {animateTo({ duration: 300 }, () => {this.toggleCard = !this.toggleCard})
​})}.width('100%').justifyContent(FlexAlign.SpaceBetween).height(50)
​// 放置传入的内容if(this.CardContent && this.toggleCard) {this.CardContent()}}.padding({left: 19.5,right: 19.5,bottom: 18.5}).margin({left: 15,right: 15,top: 15}).backgroundColor($r('app.color.white')).borderRadius(10)}
}
​
export  { HmToggleCard }


  • 页面中进行复用的主要代码:

build() {Column() {HmNavBar({ title: '任务详情' })Scroll(this.scroll) {// Scroll里面只能有一个组件Column() {HmToggleCard({ title: '基本信息' }) {this.getBaseContent()}
​HmToggleCard({ title: '车辆信息' }) {this.getTransLineContent()}
​HmToggleCard({ title: '司机信息' }) {this.getDriverContent()}
​if (this.taskDetailData.exceptionList?.length > 0) {HmToggleCard({ title: '异常信息' }) {this.getExceptionContent()}}
​if (this.taskDetailData.status === TaskTypeEnum.Waiting ||this.taskDetailData.status === TaskTypeEnum.Delivered ||this.taskDetailData.status === TaskTypeEnum.Finish) {HmToggleCard({ title: '提货信息' }) {this.getPickUpContent()}}
​
​if (this.taskDetailData.status === TaskTypeEnum.Line ||this.taskDetailData.status === TaskTypeEnum.Delivered|| this.taskDetailData.status === TaskTypeEnum.Finish) {HmToggleCard({ title: '交货信息' }) {this.getDeliverContent()}}
​}.padding({bottom: 130})}
​if (this.taskDetailData.status !== TaskTypeEnum.Finish) {// 只有在非完成情况下 才显示底部按钮this.getBottomBtn()}}.backgroundColor($r('app.color.background_page')).height('100%')
}

4.2. 设置页面

  • 自定义插槽

@Component
export struct MkCell {@Prop label: string = ''@Prop value: string = ''@Prop icon: ResourceStr = $r('app.media.ic_public_right')@Prop hasBorder: boolean = true
​@BuilderDefaultLabelBuilder() {Text(this.label).fontSize(14).fontColor($r('app.color.black'))}
​@BuilderDefaultIconBuilder() {Image(this.icon).width(20).aspectRatio(1).fillColor($r('app.color.gray'))}
​@BuilderParam customLabel: () => void = this.DefaultLabelBuilder@BuilderParam customIcon: () => void = this.DefaultIconBuilder
​build() {Row({ space: 8 }) {this.customLabel()Blank()if (this.value) {Text(this.value).fontSize(14).fontColor($r('app.color.gray'))}this.customIcon()}.width('100%').constraintSize({ minHeight: 50 }).border({ width: { bottom: this.hasBorder ? 0.6 : 0 }, color: $r('app.color.under') })}
}
​
​
@Component
export struct MkCellGroup {@BuilderDefaultBuilder() {}
​@BuilderParam default: () => void = this.DefaultBuilder
​build() {Column() {this.default()}.border({width: { top: 0.6, bottom: 0.6 },color: $r('app.color.under')}).padding({ left: 16, right: 16 }).backgroundColor($r('app.color.white'))}
}
  • 页面中进行复用的主要代码:

  build() {Column() {MkNavbar({ title: '设置' })Column({ space: 8 }) {MkCellGroup() {// 尾随闭包,MkCellGroup中只有一个 BuilderParam 即可使用尾随闭包// 多个 BuilderParam 需要用{}进行传递MkCell({hasBorder: false, customLabel: () => {this.ProfileBuilder()}})
​}
​MkCellGroup() {MkCell({ label: '收货地址管理' })MkCell({ label: '账号安全' })MkCell({ label: '消息设置' })MkCell({ label: '隐私设置' })MkCell({ label: '通用设置', hasBorder: false })}
​MkCellGroup() {MkCell({ label: '退出登录', hasBorder: false }).onClick(() => {auth.removeUser()router.back()})}}}.width('100%').height('100%').backgroundColor($r('app.color.under'))}

5.总结

当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,ArkUI引入了@BuilderParam装饰器,@BuilderParam用来装饰指向@Builder方法的变量(@BuilderParam是用来承接@Builder函数的),开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。该装饰器用于声明任意UI描述的一个元素,类似slot占位符。

1. 使用尾随闭包的方式传入:(开发者可以将尾随闭包内的内容看做@Builder装饰的函数传给@BuilderParam)

●组件内有且仅有一个使用 @BuilderParam 装饰的属性,即可使用尾随闭包。

●在初始化自定义组件时,组件后紧跟一个大括号“{}”形成尾随闭包场景。

注意:

●此场景下自定义组件不支持使用通用属性。

2. 多个@BuilderParam(无法使用尾随闭包)

需注意this指向正确。

以下示例中,Parent组件在调用this.componentBuilder()时,this指向其所属组件,即“Parent”。@Builder componentBuilder()通过this.componentBuilder的形式传给子组件@BuilderParam customBuilderParam,this指向在Child的label,即“Child”。@Builder componentBuilder()通过():void=>{this.componentBuilder()}的形式传给子组件@BuilderParam customChangeThisBuilderParam,因为箭头函数的this指向的是宿主对象,所以label的值为“Parent”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/28395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文阅读:RAM++ | Open-Set Image Tagging with Multi-Grained Text Supervision

发表时间:2023年11月16 论文地址:https://arxiv.org/pdf/2310.15200 项目地址:https://github.com/xinyu1205/recognize-anything Recognize Anything Plus Model(RAM),这是一种有效利用多粒度文本监督的开…

博通加速向Nvidia发起进攻 为何连iPhone 15都不能用“苹果智能”?

博通加速向Nvidia发起进攻 博通强调的一项优势是其 XPU 的能效。其功耗不到 600 瓦,是业内功耗最低的 AI 加速器之一。 Nvidia 的许多竞争对手都想抢占其市场主导地位。其中一个不断出现的名字是 Broadcom。仔细观察就会知道原因。其 XPU 功耗不到 600 瓦&#xff…

GPT-4并非世界模型,LeCun双手赞同!ACL力证LLM无法模拟真实世界

一直以来,支持LLM的观点之一是模型可以集成海量事实知识,作为通往「世界模拟器」的基础。虽然也有不少反对意见,但缺乏实证依据。那么,LLM能否作为世界模拟器? 最近,亚利桑那大学、微软、霍普金斯大学等机构…

飞腾银河麒麟V10安装Todesk

下载安装包 下载地址 https://www.todesk.com/linux.html 安装 yum makecache yum install libappindicator-gtk3-devel.aarch64 rpm -ivh 下载的安装包文件后台启动 service todeskd start修改配置 编辑 /opt/todesk/config/config.ini 移除自动更新临时密码 passupda…

英伟达发布Nemotron-4 340B通用模型:专为生成合成数据设计的突破性AI

引言 2023年6月14日,英伟达发布了Nemotron-4 340B通用模型,专为生成训练大语言模型的合成数据而设计。这一模型可能彻底改变训练大模型时合成数据的生成方式,标志着AI行业的一个重要里程碑。本文将详细介绍Nemotron-4 340B的各个方面&#x…

Vue43-单文件组件

一、脚手架的作用 单文件组件:xxx.vue,浏览器不能直接运行!!! 脚手架去调用webpack等第三方工具。 二、vue文件的命名规则 建议用下面的两种方式。(首字母大写!!!&#x…

CDN简介

CDN 的基本概念 CDN(Content Delivery Network),即内容分发网络。 CDN是一种分布式网络架构:它由分布在不同地理位置的服务器组成网络,这些服务器协同工作以提供内容服务。 内容分发的核心目标 确保用户能够快速、可…

Matlab自学笔记三十一:结构数组的创建、索引和预分配内存

1.概念 结构(structure array)是一种具有容器特性的数据类型,它使用称为字段的数据容器对相关数据进行分组,每个字段可以包含任何类型或大小的数据,所有元素都具有相同数量的字段和相同的字段名称。(与元胞…

Java锁之舞:性能分析与优化之路

目录 一、同步锁性能分析 (一)性能验证说明 1. 使用同步锁的代码示例 2. 不使用同步锁的代码示例 3. 结果与讨论 (二)案例初步优化分析说明 1. 使用AtomicInteger原子类尝试优化分析 2. 对AtomicInteger原子类进一步优化 …

机器学习面试-常见题目

文章目录 一、框架问题1. 监督学习和无监督学习有什么不同?2. 什么是深度学习,它与机器学习算法之间有什么联系?3. 如何评估机器学习模型的有效性?4. 如何确保模型没有过拟合?5. 什么是核技巧,有什么用处&a…

4_机械臂坐标系简介

一、坐标系的标准命名 为了规范起见,有必要给机器人和工作空间专门命名和确定专门的“标准”坐标系。 图3-27为一种典型的工况,机器人抓持某种工具,并把工具末端移动到操作者指定的位置。图3-27所示的5个坐标系就是需要命名的坐标系。这五个坐…

7z及7zip-cpp最高压缩比的免费开源压缩软件

7z介绍 7z是一种主流高效的压缩格式,它拥有极高的压缩比。在计算机科学中,7z是一种可以使用多种压缩算法进行数据压缩的档案格式。该格式最初由7-Zip实现并采用,但这种档案格式是公有的,并且7-Zip软件本身亦在GNU宽通用公共许可证…

PCIe总线-RK3588 PCIe子系统简介(八)

1.PCIe子系统 RK3588 PCIe子系统如下图所示。总共拥有5个PCIe控制器。PCIe30X4(4L)支持RC和EP模式,其他4个仅支持RC模式。ITS port 1连接PCIe30X4(4L)和PCIe30X2(2L)控制器,PCIe30X4(4L)和PCIe30X2(2L)控制器使用PCIe3.0 PIPE PHY。ITS port 0连接PCIe3…

RIP路由附加度量值(华为)

#交换设备 RIP路由附加度量值 RIP(Routing Information Protocol)路由协议中的附加度量值是指在RIP路由原来度量值的基础上所增加的额外度量值,通常以跳数来表示。这个附加度量值可以是正值,也可以是负值,用于影响路…

关于STM32上用HID HOST调鼠标数据的解析

一、前言 关于这章主要是基于我前面的那篇文章 链接: 关于怎么用Cubemx生成的USBHID设备实现读取一体的鼠标键盘设备(改进版) https://blog.csdn.net/qq_29187987/article/details/139535648?spm1001.2014.3001.5501 引用的文章的简介 引用的这篇文…

数据库概述1

数据:描述事物的符号记录称为数据; 包括数字、图片、音频等; 数据库:长期储存在计算机内有组织、可共享的大量数据的集合;数据库中的数据按照一定的数据模型组织、描述和存储,具有较小的数据冗余、较高的数…

STM32学习笔记(一)--时钟树详解

(1)时钟概述;时钟是具有周期性的脉冲信号,最常用的是占空比50%的方波。(时钟相当于单片机的脉搏;STM32本身非常复杂,外设非常的多,为了保持低功耗工作,STM32 的主控默认不…

【Python】深入了解 AdaBoost:自适应提升算法

我们都找到天使了 说好了 心事不能偷藏着 什么都 一起做 幸福得 没话说 把坏脾气变成了好沟通 我们都找到天使了 约好了 负责对方的快乐 阳光下 的山坡 你素描 的以后 怎么抄袭我脑袋 想的 🎵 薛凯琪《找到天使了》 在机器学习的领域中&#x…

算法工程师 | 如何快速 了解,掌握一个算法!脚踏实地,迎着星辰,向前出发 ~

本文是一些碎碎念 希望对正在迈向 算法工程师道路的你 有所裨益 一般来说,代码 中会有很多 算法实现的细节,但论文可能并没有体现,所以能够尝试自己 仔细阅读论文,手动复现代码,基本上来说对 这个 算法 你有了全…