鸿蒙开发:熟知@BuilderParam装饰器
前言
本文代码案例基于Api13。
在实际的开发中,我们经常会遇到自定义组件的情况,比如通用的列表组件,选项卡组件等等,由于使用方的样式不一,子组件是动态变化的,针对这一情况,就不得不让使用方把子组件视图传递过来,如何来接收这个UI视图,这就是@BuilderParam装饰器的作用。
简单案例
简单封装一个通用的List组件,由于每个列表的数据和UI布局都是不一样的,那么这两块就需要暴露给使用方,代码如下:
/*** AUTHOR:AbnerMing* DATE:2025/2/13* INTRODUCE:通用的列表组件* */
@Component
export struct ListView {dataList?: Object[] //数据源@BuilderParam itemLayout: (item: Object, index: number) => void //子视图build() {List() {ForEach(this.dataList, (item: Object, index: number) => {ListItem() {this.itemLayout(item, index)}})}}
}
以上的自定义List组件,我们就可以用在任何页面,只需要传递数据和子视图即可。
@Entry
@Component
struct Index {@BuilderitemLayout(item: Object, index: number) {Text(item.toString())}build() {Column() {ListView({dataList: [0, 1, 2, 3, 4, 5, 6],itemLayout: this.itemLayout})}.height('100%').width('100%')}
}
@BuilderParam装饰器让UI组件赋予了动态的变化,可以根据自身需要实现不同的效果,避免了实例增加了相同的功能,从而实现更高程度的组件复用和代码解耦。
使用方式
@BuilderParam装饰器,常见于自定义组件,暴露给使用方进行调用,用来承接@Builder装饰器修饰的函数,使用方式很简单,格式如下:
@BuilderParam test: () => void
如果接收参数,直接在括号中添加即可。
除了正常的由调用者传递UI组件之外,我们也可以初始化一个默认的视图,直接在后面等于即可,这样在未传递的话就会加载默认的视图。
@Builder
testView() {}@BuilderParam test: () => void = this.testView()
this指向问题
如下所示,我们自定义了一个组件,定义了两个@BuilderParam,用于接收传递的UI视图:
@Component
export struct TestView {testContent: string = "TestView"@BuilderParam layout: () => void@BuilderParam layout2: () => voidbuild() {Column() {if (this.layout != undefined) {this.layout()}if (this.layout2 != undefined) {this.layout2()}}}
}
我们通过三种方式,分别调用@Builder修饰的函数。
@Entry
@Component
struct Index {testContent: string = "Index"@BuildertestView() {Text(`${this.testContent}`).fontSize(20).margin({ top: 20 }).fontWeight(FontWeight.Bold)}build() {Column() {this.testView()TestView({ layout: this.testView })TestView({layout2: () => {this.testView()}})}.height('100%').width('100%')}
}
运行之后,效果如下:

我们可以看到,直接调用@Builder修饰的函数,也就是this.testView()这行代码,this指向的是当前的Index类,其值也是取的Index中值。
当我们以参数的形式,传递给@BuilderParam时,也就是TestView({ layout: this.testView })这行代码,可以发现,其this并不是指的是Index类,而是自定义组件TestView,取的是TestView中所定义的值。
当我们针对自定义组件,换种方式使用时,也就是如下方式使用:
TestView({layout2: () => {this.testView()}})
可以发现,this又切换为了当前类Index,这是因为箭头函数的this指向的是宿主对象,所以其值取的是Index类中的。
所以在有@BuilderParam传递UI视图时,一定要注意this的指向问题,这也是为什么很多同学遇到在@Builder修饰的函数中为什么不刷新数据的问题,其原因就是this指向不对。
数据更新
更新@BuilderParam装饰器,本意就是更新对应的@Builder修饰的函数,这个在《鸿蒙开发:了解@Builder装饰器》一篇中已经重点做了讲解,这里再重新概述一下。
简单自定义一个组件,使用 @BuilderParam装饰器,对外暴露一个UI视图。
@Component
export struct TestView {@BuilderParam layout: () => voidbuild() {Column() {if (this.layout != undefined) {this.layout()}}}
}
上面已经讲述过this指向问题了,如果数据在本页面内,那么一定要使用箭头函数来调用@Builder修饰的函数,才能实现数据的更新。
@Entry
@Component
struct Index {@State testContent: string = "测试数据一"@BuildertextView() {Text(this.testContent).fontSize(20).fontWeight(FontWeight.Bold)}build() {Column() {TestView({layout: () => {this.textView()}})Button("点击").onClick(() => {this.testContent = "测试数据二"})}.height('100%').width('100%')}
}
相关总结
在声明@BuilderParam的时候,如果未有默认值,那么在不传递的情况下,会发生异常崩溃,为了解决这一问题,有两种方案,方案一,主动设置默认值:
@Builder
testView() {}@BuilderParam test: () => void = this.testView()
方案二,在调用的地方进行非空校验:
@BuilderParam test: () => voidbuild() {if (this.test != undefined) {this.test()}}
@BuilderParam用于接收@Builder定义的函数,私有和全局都可以。
定义全局的@Builder。
@Builder
export function TextView() {Text("测试数据一").fontSize(20).fontWeight(FontWeight.Bold)
}
调用
@Entry
@Component
struct Index {build() {Column() {TestView({ layout: TextView })}.height('100%').width('100%')}
}相关文章:
鸿蒙开发:熟知@BuilderParam装饰器
前言 本文代码案例基于Api13。 在实际的开发中,我们经常会遇到自定义组件的情况,比如通用的列表组件,选项卡组件等等,由于使用方的样式不一,子组件是动态变化的,针对这一情况,就不得不让使用方把…...
光谱相机在天文学领域的应用
天体成分分析 恒星成分研究:恒星的光谱包含了其大气中各种元素的吸收和发射线特征。通过光谱相机精确测量这些谱线,天文学家能确定恒星大气中氢、氦、碳、氮、氧等元素的含量。如对太阳的光谱分析发现,太阳大气中氢元素占比约 71%࿰…...
不到1M的工具,使用起来非常丝滑!
今天给大家推荐两款电脑上超实用的小软件,分别是倒计时工具和关机助手,用起来特别顺手,希望能帮到大家。 关机助手 帮你自动关机 先说说关机助手。这款软件简直太方便了!它是一款免安装的小工具,体积超小,…...
软考高级《系统架构设计师》知识点(二)
操作系统知识 操作系统概述 操作系统定义:能有效地组织和管理系统中的各种软/硬件资源,合理地组织计算机系统工作流程,控制程序的执行,并且向用户提供一个良好的工作环境和友好的接口。操作系统有三个重要的作用: 管理…...
深入解析操作系统控制台:阿里云Alibaba Cloud Linux(Alinux)的运维利器
作为一位个人开发者兼产品经理,我的工作日常紧密围绕着云资源的运维和管理。在这个过程中,操作系统扮演了至关重要的角色,而操作系统控制台则成为了我们进行系统管理的得力助手。本文将详细介绍阿里云的Alibaba Cloud Linux操作系统控制台的功…...
云原生AI Agent应用安全防护方案最佳实践(上)
当下,AI Agent代理是一种全新的构建动态和复杂业务场景工作流的方式,利用大语言模型(LLM)作为推理引擎。这些Agent代理应用能够将复杂的自然语言查询任务分解为多个可执行步骤,并结合迭代反馈循环和自省机制࿰…...
Java Virtual Machine(JVM)
JVM跨平台原理 跨平台:一次编译,到处运行 本质:不同操作系统上运行的JVM不一样,只需要把java程序编译成一份字节码文件,JVM执行不同的字节码文件。 Java是高级语言,提前编译一下(变成字节码文件…...
vue前端可视化大屏页面适配方案
参考了其他博主的代码,但发现会有滚动条,并且居中的位置不太对,所以改了一下css,修复了这些问题,直接上代码 <template> <div class"ScaleBoxA"><divclass"ScaleBox"ref"Sca…...
Docker中安装MySql方法
使用Docker安装MySQL的详细步骤,涵盖单机部署、数据持久化、网络配置等内容: 1. 安装Docker 如果尚未安装Docker,请先安装: Windows/macOS:下载 Docker Desktop 并安装。 Linux: curl -fsSL https://get.docker.com | bash sudo systemctl start docker sudo system…...
云轴科技ZStack+神州鲲泰,全面支持企业私有化部署DeepSeek模型
如今,DeepSeek的影响力正呈指数级扩散。全球范围内,从科技巨头到初创企业,纷纷投身于DeepSeek系列模型的接入浪潮。为应对企业数据安全与算力高效管理的双重挑战,云轴科技ZStack联合神州鲲泰,基于昇腾算力底座共推ZSta…...
$ npx electron-forge import 一直报权限问题 resource busy or locked,
jackLAPTOP-7DHDAAL0 MINGW64 /e/project/celetron-project/my-electron-app (master) $ npx electron-forge import > Checking your system > Checking git exists > Checking node version > Checking packageManager version √ Found node22.14.0 √ Found gi…...
LLM:GPT 系列
阅读原文: LLM:Qwen 系列 GPT(Generative Pre-trained Transformer)是生成式预训练语言模型,基于 Transformer 架构,专注于通过自回归的方式生成自然语言文本,即给定一个输入序列 x { x 1 , …...
2025年:边缘计算崛起下运维应对新架构挑战
一、引言 随着科技的飞速发展,2025年边缘计算正以前所未有的速度崛起,给运维行业带来了全新的架构挑战。在这个充满机遇与挑战的时代,美信时代公司的美信监控易运维管理软件成为运维领域应对这些挑战的有力武器。 二、边缘计算崛起带来的运维…...
【深度学习模型分类】
深度学习模型种类繁多,涵盖了从基础到前沿的多种架构。以下是主要模型的分类及代表性方法: 1. 基础模型 1.1 多层感知机(MLP) 特点:全连接神经网络,适用于结构化数据。 应用:分类、回归任务…...
【Java报错已解决】org.springframework.beans.factory.BeanCreationException
???很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。??? 欢迎订阅本专栏 目录…...
理解 WebGPU 中的 GPUQueue:GPU 的命令队列
在现代图形编程中,与 GPU 的交互变得越来越高效和灵活,而 WebGPU API 的出现更是为 Web 开发者带来了强大的图形处理能力。其中, GPUQueue 作为 WebGPU 的核心接口之一,扮演着至关重要的角色。本文将详细介绍 GPUQueue 的概…...
电脑显示器无信号是什么原因?查看解决方法
在我们使用电脑的过程中,常遇到的一个问题就是,开机电脑显示器无信号输入。这种故障情况它会导致电脑无法正常显示图像,影响电脑的使用。但是电脑显示器无信号的原因可能有很多,我们需要一一去排除解决。下面便为大家一起来介绍下…...
Debian系发行版通用软件彻底卸载指南
1. 确定软件包名称 # 查看已安装软件列表 dpkg -l | grep 关键词 或 apt list --installed | grep 关键词# 查找二进制文件路径(用于推测包名) which 程序名 # 查找可执行文件路径 whereis 程序名 # 查找相关文件2. 服务检查和停止 # 检查是否有相关…...
微信小程序地图标记点,安卓手机一次性渲染不出来的问题
问题描述: 如果微信小程序端,渲染的标记物太多,安卓手机存在标记物不显示的问题,原因初步判断是地图还没有渲染完,标记物数据已经加载完了,导致没有在地图上显示。 解决办法: 使用map组件的b…...
LabVIEW软件需求开发文档参考
在项目开发的工作历程中,精准把握项目需求无疑是成功打造整个项目的首要关键步骤,同时也是一个至关重要且不可忽视的核心环节。明确且详尽的项目需求就如同建筑的基石,为后续的设计、开发、测试等一系列工作提供了坚实的支撑和清晰的指引。倘…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
