HarmonyOs应用《日记本》开发第10篇 - @Builder 构建器与组件复用
在 ArkUI 开发中Builder是实现 UI 片段复用的核心装饰器。它让开发者可以将复杂的 UI 拆分为多个可维护的方法提高代码的可读性和复用性。本篇将以日记项目的三个页面为例深入探讨 Builder 的使用模式和最佳实践。Builder 基本语法BuilderMethodName(parameters):void{// UI 描述}基本示例Componentstruct Index{BuilderHeaderBar():void{Row(){Text(我的日记).fontSize(22).fontWeight(FontWeight.Bold).fontColor(#333).margin({left:20})Blank()Button(){...}}.width(100%).height(56).backgroundColor(#FFF)}build():void{Column(){this.HeaderBar()// 调用 Builder 方法}}}日记项目中的 Builder 全景Index 页面 — 4 个 BuilderEntryComponentstruct Index{build():void{Column(){this.HeaderBar()// 顶部标题栏if(this.isLoading){// 内联加载状态}elseif(this.diaries.length0){this.EmptyView()// 空状态视图}else{this.DiaryList()// 日记列表}}}BuilderHeaderBar():void{...}// 1. 标题栏BuilderEmptyView():void{...}// 2. 空状态BuilderDiaryList():void{...}// 3. 列表容器BuilderDiaryCard(item:DiaryItem):void{...}// 4. 日记卡片}DiaryEdit 页面 — 6 个 BuilderEntryComponentstruct DiaryEdit{build():void{Column(){this.NavBar()// 1. 导航栏Scroll(){Column(){this.DateSection()// 2. 日期选择区this.WeatherSection()// 3. 天气选择区this.MoodSection()// 4. 心情选择区this.TitleSection()// 5. 标题输入区this.ContentSection()// 6. 内容输入区}}}}}DiaryDetail 页面 — 3 个 BuilderEntryComponentstruct DiaryDetail{build():void{Column(){this.NavBar()// 1. 导航栏if(this.loading){// 内联加载状态}elseif(this.diary){this.DetailContent()// 2. 详情内容}else{// 内联不存在状态}}.bindContentCover($$this.showDeleteDialog,this.DeleteDialog())// 3. 删除弹窗}}Builder 进阶用法1. 带参数的 BuilderBuilderDiaryCard(item:DiaryItem):void{Column(){// 日期行Row(){Text(item.date).fontSize(14).fontWeight(FontWeight.Medium).fontColor(#FF6B6B)Blank()Text(getWeatherByKey(item.weather).emoji).fontSize(18).margin({right:8})Text(getMoodByKey(item.mood).emoji).fontSize(18)}.width(100%).alignItems(VerticalAlign.Center)// 标题Text(item.title).fontSize(17).fontWeight(FontWeight.Bold).fontColor(#333).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis}).margin({top:8})// 内容预览Text(item.content).fontSize(14).fontColor(#888).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis}).margin({top:6})// 底部信息Row(){Text(diaryStore.formatDateTime(item.updateTime)).fontSize(11).fontColor(#CCC)}.width(100%).margin({top:8})}.width(100%).padding(16).backgroundColor(#FFF).borderRadius(16).shadow({radius:8,color:#0D000000,offsetX:0,offsetY:2})}在ForEach中使用BuilderDiaryList():void{List({space:12}){ForEach(this.diaries,(item:DiaryItem){ListItem(){this.DiaryCard(item)// 传递参数}.onClick((){router.pushUrl({url:pages/DiaryDetail,params:{id:item.id}});})},(item:DiaryItem)item.id)}.width(100%).layoutWeight(1).padding({top:12,bottom:20,left:16,right:16})}2. 条件渲染的 BuilderBuilderNavBar():void{Row(){Text(返回).fontSize(16).fontColor(#666).onClick((){router.back();})Blank()if(this.diary){// 条件渲染只有日记数据存在时才显示编辑按钮Text(编辑).fontSize(16).fontColor(#FF6B6B).fontWeight(FontWeight.Medium).onClick((){router.pushUrl({url:pages/DiaryEdit,params:{id:this.diaryId}});})}}.width(100%).height(56).backgroundColor(#FFF).padding({left:20,right:20}).alignItems(VerticalAlign.Center)}3. 事件绑定的 BuilderBuilderWeatherSection():void{Column(){Text(天气).fontSize(15).fontColor(#666).margin({top:16,left:4})Row(){ForEach(WeatherList,(item:MoodWeatherItem){Column(){Text(item.emoji).fontSize(28)Text(item.label).fontSize(12).fontColor(this.weatheritem.key?#FF6B6B:#999).margin({top:4})}.width(18%).height(70).borderRadius(10).backgroundColor(this.weatheritem.key?#FFF0F0:#FFF).border(this.weatheritem.key?{width:1.5,color:#FF6B6B}:{width:0,color:#FFF}).onClick((){this.weatheritem.key;// 事件处理})})}}}4. 嵌套调用的 BuilderBuilderDetailContent():void{Scroll(){Column(){// 日记主体卡片Column(){// 日期行Row(){...}// 分隔线Divider().color(#F0F0F0).margin({top:16,bottom:16})// 标题if(this.diary!.title){Text(this.diary!.title)...}// 正文Text(this.diary!.content)...// 底部时间Column(){...}}.shadow({...})// 删除按钮Button(删除此日记).onClick((){this.showDeleteDialogtrue;// 触发弹窗})}}}5. 全屏弹窗 BuilderBuilderDeleteDialog():void{Column(){Column(){Text(确认删除).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#333).margin({top:24})Text(删除后无法恢复确定删除这篇日记吗).fontSize(14).fontColor(#888).margin({top:12,bottom:24})Divider().color(#F0F0F0)Row(){Text(取消).layoutWeight(1).onClick((){this.showDeleteDialogfalse;})Divider().vertical(true).height(48)Text(删除).layoutWeight(1).onClick((){this.showDeleteDialogfalse;this.deleteDiary();})}}.width(80%).backgroundColor(#FFF).borderRadius(16)}.width(100%).height(100%).justifyContent(FlexAlign.Center).backgroundColor(#99000000)// 半透明遮罩}Builder 的设计模式模式 1区域划分将页面按功能区域拆分DiaryEdit 页面 ├── NavBar() → 导航区域 ├── DateSection() → 日期区域 ├── WeatherSection() → 天气区域 ├── MoodSection() → 心情区域 ├── TitleSection() → 标题区域 └── ContentSection() → 内容区域模式 2状态分支根据状态渲染不同 UIIndex 页面 ├── HeaderBar() → 始终显示 ├── [加载中] → 内联 ├── EmptyView() → 空状态 └── DiaryList() → 有数据时模式 3列表项模板ForEach(this.diaries,(item:DiaryItem){ListItem(){this.DiaryCard(item)// 每个列表项复用同一模板}},(item:DiaryItem)item.id)模式 4弹窗模板.bindContentCover($$this.showDeleteDialog,this.DeleteDialog())Builder 与组件通信通过 State 共享Builder 方法可以访问组件的 State 变量Stateweather:stringsunny;BuilderWeatherSection():void{// 直接访问 this.weather.backgroundColor(this.weatheritem.key?#FFF0F0:#FFF).onClick((){this.weatheritem.key;// 修改 State})}通过参数传递BuilderDiaryCard(item:DiaryItem):void{Text(item.title)// 使用传入的参数Text(item.content)}Builder 最佳实践1. 单一职责每个 Builder 只负责一个 UI 区域// ✅ 好的做法BuilderNavBar():void{...}BuilderDateSection():void{...}BuilderWeatherSection():void{...}// ❌ 不好的做法BuilderBigChunk():void{// 导航栏 日期 天气 心情 标题 内容全写在一起}2. 合理命名使用描述性名称让人一看就知道 Builder 渲染什么// ✅ 清晰的命名BuilderHeaderBar():void{...}BuilderEmptyView():void{...}BuilderDiaryCard(item:DiaryItem):void{...}BuilderDeleteDialog():void{...}// ❌ 模糊的命名BuilderView1():void{...}BuilderBuild():void{...}3. 避免过深嵌套// ✅ 扁平化结构build():void{Column(){this.NavBar()this.DateSection()this.WeatherSection()this.MoodSection()this.TitleSection()this.ContentSection()}}小结Builder是 ArkUI 中实现 UI 复用和代码组织的利器特性说明参数传递支持传入参数实现模板化状态访问可访问组件 State 变量条件渲染支持内部 if-else事件绑定支持 onClick 等事件嵌套调用Builder 可调用其他 Builder弹窗构建可配合 bindContentCover 实现弹窗通过合理使用 Builder日记项目将复杂的 UI 拆分为清晰的小块每个 Builder 负责一个独立区域使代码易于维护和扩展。

相关新闻

LinkedIn资料完整,为什么还是很少收到招聘人员联系?|蒸汽求职分享

LinkedIn资料完整,为什么还是很少收到招聘人员联系?|蒸汽求职分享

**摘要:**LinkedIn资料完整,只能说明页面信息较齐全,并不代表招聘人员能快速判断候选人适合什么岗位。Headline、About、经历标题和项目描述需要共同传递清楚的职业方向,同时保持信息真实,并与简历和实际能力一致。 学…

2026/7/25 23:14:10 阅读更多 →
本地大模型部署优化:解决Hermes Agent卡顿与显存溢出问题

本地大模型部署优化:解决Hermes Agent卡顿与显存溢出问题

在本地部署大模型运行 Hermes Agent 时,很多开发者都会遇到卡顿、响应变慢甚至显存溢出的问题。这些问题不仅影响开发效率,更让本地 AI 应用的体验大打折扣。本文将从硬件配置、模型选择、参数调优到系统优化,为你提供一套完整的解决方案。 无论你是刚接触 Hermes Agent 的…

2026/7/25 23:13:10 阅读更多 →
Swift宏功能在SmartCodable中的应用:提升开发效率的5个实用技巧

Swift宏功能在SmartCodable中的应用:提升开发效率的5个实用技巧

Swift宏功能在SmartCodable中的应用:提升开发效率的5个实用技巧 【免费下载链接】SmartCodable SmartCodable is a data parsing library built on Swift’s Codable, designed for simple usage and strong real-world compatibility. It gracefully handles missi…

2026/7/25 23:13:10 阅读更多 →

最新新闻

计算机小程序毕设实战-基于 Django 的高校停车服务微信小程序设计【完整源码+LW+部署说明+演示视频,全bao一条龙等】

计算机小程序毕设实战-基于 Django 的高校停车服务微信小程序设计【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/25 23:23:14 阅读更多 →
签名、版本元数据与 Release 卫生检查

签名、版本元数据与 Release 卫生检查

功能全部就绪之后,发布工程要回答的问题变得朴素:这个包,真的是我们以为的那个包吗? 元数据对不对、签名是不是发布证书、内容干不干净、构建新不新鲜。这篇按我们 P7 阶段的真实门禁讲这四问。1. 先搞清楚:鸿蒙工程里…

2026/7/25 23:23:14 阅读更多 →
DL3DV-10K数据集实战:用Difix3D+训练高质量3D模型

DL3DV-10K数据集实战:用Difix3D+训练高质量3D模型

DL3DV-10K数据集实战:用Difix3D训练高质量3D模型 【免费下载链接】difix_ref 项目地址: https://ai.gitcode.com/hf_mirrors/nvidia/difix_ref Difix3D是一款基于单步扩散模型的3D重建增强工具,能够显著提升3D模型的质量。本文将详细介绍如何利用…

2026/7/25 23:23:14 阅读更多 →
小程序毕设项目:基于Django的校园停车动态监测与辅助小程序开发 轻量化校园智慧停车服务小程序 (源码+文档,讲解、调试运行,定制等)

小程序毕设项目:基于Django的校园停车动态监测与辅助小程序开发 轻量化校园智慧停车服务小程序 (源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/25 23:23:14 阅读更多 →
AI Agent五大设计模式解析与应用实践

AI Agent五大设计模式解析与应用实践

1. 什么是AI Agent设计模式在人工智能领域,AI Agent设计模式就像是建筑师的蓝图,它定义了智能体如何感知环境、做出决策并执行行动。这些模式不是凭空想象出来的,而是经过大量实践验证的最佳实践方案。我见过太多团队在开发AI系统时&#xff…

2026/7/25 23:23:14 阅读更多 →
使用gimme构建高效Go开发工作流:专家级建议

使用gimme构建高效Go开发工作流:专家级建议

使用gimme构建高效Go开发工作流:专家级建议 【免费下载链接】gimme Install go, yay! 项目地址: https://gitcode.com/gh_mirrors/gi/gimme gimme是一款轻量级Go版本管理工具,能够帮助开发者快速安装、切换和管理多个Go环境,让Go开发工…

2026/7/25 23:22:14 阅读更多 →

日新闻

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您的…

2026/7/25 0:00:35 阅读更多 →
C++ string类模拟实现:从深拷贝到内存管理的完整指南

C++ string类模拟实现:从深拷贝到内存管理的完整指南

1. 项目概述:为什么我们要“手撕”string类?在C的学习道路上,尤其是从C语言过渡到C的“初阶”阶段,string类绝对是一个绕不开的核心。标准库里的std::string用起来太方便了,、find、substr,几个操作符和函数…

2026/7/25 0:00:35 阅读更多 →
三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

1. 先搞清楚“三角洲寻宝鼠”到底是什么工具从名称来看,“三角洲寻宝鼠”更像是一个资源查找或文件检索类工具,而不是游戏或娱乐软件。这类工具的核心价值在于帮助用户快速定位特定资源,比如文档、图片、压缩包或特定格式的文件。如果你经常需…

2026/7/25 0:00:35 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/25 5:08:22 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/25 5:13:53 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 18:52:18 阅读更多 →

月新闻