【最新鸿蒙应用开发】——鸿蒙中的“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.rhkb.cn/news/351291.html

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

相关文章

机器学习笔记 - 用于3D点云数据分割的Point Net的训练

一、数据集简述 ​在本教程中,我们将学习如何在斯坦福 3D 室内场景数据集 ( S3DIS )上训练 Point Net 进行语义分割。S3DIS 是一个 3D 数据集,包含来自多栋建筑的室内空间点云,占地面积超过 6000 平方米。Point Net使用整个点云,能够执行分类和分割任务。如果你一直在关注 …

LVS负载均衡集群企业级应用实战-LVS-DR(四)

目录 LVS-DR 一. 环境准备 二. 对虚拟主机操作 三. 对真实服务器操作 四. 打开网页测试 LVS-DR 一. 环境准备 三台虚拟机,都要在同一网段内,统一关闭防火墙和selinux,时间同步,配置好YUM源。系统用centos和roucky都行。 主…

matlab-2-simulink-小白教程-如何绘制电路图进行电路仿真

以上述电路图为例:包含D触发器,时钟CLK,与非门 一、启动simulink的三种方式 方式1 在MATLAB的命令行窗口输入“Simulink”命令。 方式2 在MATLAB主窗口的“主页”选项卡中,单击“SIMULINK”命令组中的Simulink命令按钮。 方式3 从MATLAB…

[Linux] TCP协议介绍(3): TCP协议的“四次挥手“过程、状态分析...

TCP协议是面向连接的 上一篇文章简单分析了TCP通信非常重要的建立连接的"三次握手"的过程 本篇文章来分析TCP通信中同样非常重要的断开连接的"四次挥手"的过程 TCP的"四次挥手" TCP协议建立连接 需要"三次握手". "三次挥手&q…

光明网发稿投稿流程与要求,光明日报如何投稿?附光明网多少钱(价格表)

对于想要在光明网发稿的作者来说,媒介多多网发稿平台是一个绝佳的投稿选择。光明网作为国内一流的新闻媒体平台,其严谨的文章审核标准和广泛的读者基础吸引着无数作者。然而,由于其严格的发稿标准,一些作者可能会遇到一些困难&…

基于Python+OpenCV高速公路行驶车辆的速度检测系统

简介: 基于Python和OpenCV的高速公路行驶车辆的速度检测系统旨在实时监测高速公路上的车辆,并测量它们的速度。该系统可以用于交通监控、道路安全管理等领域,为相关部门提供重要的数据支持。 系统实现: 视频流输入:系…

快速理解 Node.js 版本差异:3 分钟指南

Node.js 是一个广泛使用的 JavaScript 运行时环境,允许开发者在服务器端运行 JavaScript 代码。随着技术的发展,Node.js 不断推出新版本,引入新特性和改进。了解不同版本之间的差异对于开发者来说至关重要。以下是一个快速指南,帮…

Docker安装Nginx(各种错误版)

Docker安装-CSDN博客 看过程就一点点看,看结果直接看最后 安装启动Docker之后 docker run -d -p 81:81 --name nginx nginx 这样没有指定版本 docker run:启动一个新的容器。-d:以分离模式运行容器(后台运行)。-p 81:81&…

【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)

最终效果 文章目录 最终效果前言素材下载简单搭建环境控制小鸟生成弹簧 限制小鸟的控制范围弹簧线的显示隐藏飞行新增木头木头销毁不同血量的木头状态配置更多物品爆炸效果创建敌人的小猪创建多个小鸟循环游戏结束相机跟随加分特效不同定义技能的鸟加速鸟回旋鸟爆炸鸟效果 轨迹…

【MySQL】服务器配置和管理

本文使用的MySQL版本是8.0 MySQL服务器介绍 MySQL服务器通常说的是mysqld程序。 mysqld 是 MySQL 数据库服务器的核心程序,负责处理客户端的请求、管理数据库和执行数据库操作。管理员可以通过配置文件和各种工具来管理和监控 mysqld 服务器的运行 官方文档&…

YOLOv10涨点改进SPPF创新结构,重新设计全局平均池化层和全局最大池化层,增强全局视角信息和不同尺度大小的特征

本文改进:SPPF_improve利用全局平均池化层和全局最大池化层,加入一些全局背景信息和边缘信息,从而获取全局视角信息并减轻不同尺度大小所带来的影响,强烈推荐,适合直接使用,paper创新级。 目录 1,YOLOv10介绍 1.1 C2fUIB介绍 1.2 PSA介绍 1.3 SCDown 2.SPP &SP…

Hvv--知攻善防应急响应靶机--Linux1

HW–应急响应靶机–Linux1 所有靶机均来自 知攻善防实验室 靶机整理: 夸克网盘:https://pan.quark.cn/s/4b6dffd0c51a#/list/share百度云盘:https://pan.baidu.com/s/1NnrS5asrS1Pw6LUbexewuA?pwdtxmy 官方WP:https://mp.weixin.…

工业自动化领域常见的通讯协议

工业自动化领域常见的通讯协议,包括PROFINET、PROFIBUS、Modbus、Ethernet/IP、CANopen、DeviceNet和BACnet。通过分析这些协议的技术特点、应用场景及优势,比较它们在工业自动化中的性能和适用性,帮助选择最合适的协议以优化系统性能和可靠性…

基于某评论的TF-IDF下的LDA主题模型分析

完整代码: import numpy as np import re import pandas as pd import jieba from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.decomposition import LatentDirichletAllocationdf1 pd.read_csv(小红书评论.csv) # 读取同目录下csv文件…

Java | Leetcode Java题解之第151题反转字符串中的单词

题目: 题解: class Solution {public String reverseWords(String s) {StringBuilder sb trimSpaces(s);// 翻转字符串reverse(sb, 0, sb.length() - 1);// 翻转每个单词reverseEachWord(sb);return sb.toString();}public StringBuilder trimSpaces(S…

HAL库开发--SPI的配置方式和读写操作

知不足而奋进 望远山而前行 目录 文章目录 前言 目标 内容 需求 SPI配置 SPI编码 OLED驱动拷贝 OLED的GPIO初始化修改 实现SPI的读写 总结 前言 SPI(Serial Peripheral Interface)是一种常见的串行通信协议,在嵌入式系统中被广泛…

记录一次root过程

设备: Redmi k40s 第一步, 解锁BL(会重置手机系统!!!所有数据都会没有!!!) 由于更新了澎湃OS系统, 解锁BL很麻烦, 需要社区5级以上还要答题。 但是,这个手机…

Java基础——网络编程(一)

初识网络编程 网络编程:在网络通信协议下,不同计算机上运行的程序,进行的数据传输 应用场景:即时通信、网游对战、金融证券、国际贸易、邮件…… BS架构的优缺点: 1、不需要开发客户端,只需要页面服务端 2、…

可视化大屏开发系列——页面布局

页面布局是可视化大屏的基础,想要拥有一个基本美观的大屏,就得考虑页面整体模块的宽高自适应,我们自然就会想到具有强大灵活性flex布局,再借助百分比布局来辅助。至此,大屏页面布局问题即可得到解决。 写在前面&#x…

Java高级技术探索:深入理解JVM内存分区与GC机制

文章目录 引言JVM内存分区概览垃圾回收机制(GC)GC算法基础常见垃圾回收器ParNew /Serial old 收集器运行示意图 优化实践结语 引言 Java作为一门广泛应用于企业级开发的编程语言,其背后的Java虚拟机(JVM)扮演着至关重…