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/10/25 11:34:20 阅读更多 →
本地大模型部署优化:解决Hermes Agent卡顿与显存溢出问题

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

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

2026/10/23 23:59:22 阅读更多 →
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/10/24 4:13:11 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →