HarmonyOS7 @Builder 把重复 UI 收起来:别急着拆组件
2026/7/21 23:59:36 网站建设 项目流程


文章目录

      • 前言
      • 为什么这个问题经常被写乱
      • Builder 和组件怎么选
      • 先把页面目标想清楚
      • 完整 ArkUI 示例
      • 把关键代码一段段拆开
      • Builder 不适合装太多业务
      • 新手最容易踩的坑
      • 放进真实项目还要补什么
      • 写在最后

前言

页面里重复三次以上的标题栏、设置行、状态标签,复制粘贴肯定能跑,但后面改样式会很痛苦。

这时候很多人会立刻拆组件。我的习惯是先判断:这个 UI 片段是不是只在当前页面复用?有没有独立状态?会不会跨页面使用?如果答案都偏轻,用@Builder更合适。

@Builder适合收起当前组件里的局部重复,不是所有组件拆分的替代品。

为什么这个问题经常被写乱

@Builder 把重复 UI 收起来 这类内容很容易被写成“代码能跑就算讲完了”,但对初学者来说,这恰恰是最不够的地方。真正让人卡住的,往往不是某个组件名记不住,而是不知道这段代码为什么要这样拆、状态为什么要这样放、以后需求变化时应该从哪里改。

所以这篇文章不只想给你一个能跑的例子,更想把背后的判断过程讲清楚。你只要把这个判断过程吃透,后面自己改页面、补需求、查问题时,心里会稳很多。

Builder 和组件怎么选

写法适合场景代价
直接复制一两处临时 UI后期样式容易漂移
@Builder同页面局部重复不适合承载复杂业务状态
独立组件多页面复用、有明确接口命名和参数要设计清楚

设置页是@Builder很适合的场景:分组标题、普通设置行、开关设置行都很像,但还没必要拆成一堆文件。

复制粘贴省的是当下几分钟,后面统一改样式时会还回来。

先把页面目标想清楚

在真正写代码之前,先别急着盯着 API。更有用的做法是先想清楚:这个页面到底想解决什么问题,用户最在意的反馈是什么,哪些状态必须一直保持一致。

当你先把这条主线想明白,再回头看组件和状态设计,很多选择都会顺理成章。对小白来说,这一步尤其重要,因为它能帮你从“照着抄”慢慢过渡到“看得懂、改得动”。

完整 ArkUI 示例

下面这个设置页用三个@Builder收起重复 UI:分组标题、普通设置行、开关设置行。

@Entry@Componentstruct SettingsBuilderPage{@StatepushEnabled:boolean=true@StateuseCellular:boolean=false@BuilderSectionTitle(title:string){Text(title).fontSize(13).fontColor('#888888').width('100%').padding({left:4,top:12,bottom:6})}@BuilderSettingRow(title:string,desc:string,value:string){Row(){Column({space:4}){Text(title).fontSize(16).fontColor('#222222')Text(desc).fontSize(12).fontColor('#888888').maxLines(1)}.alignItems(HorizontalAlign.Start).layoutWeight(1)Text(value).fontSize(14).fontColor('#666666')Text('>').fontSize(16).fontColor('#BBBBBB').margin({left:6})}.padding(14).backgroundColor(Color.White)}@BuilderSwitchRow(title:string,desc:string,enabled:boolean,onChange:(value:boolean)=>void){Row(){Column({space:4}){Text(title).fontSize(16)Text(desc).fontSize(12).fontColor('#888888')}.alignItems(HorizontalAlign.Start).layoutWeight(1)Toggle({type:ToggleType.Switch,isOn:enabled}).onChange((value:boolean)=>onChange(value))}.padding(14).backgroundColor(Color.White)}build(){Column(){this.SectionTitle('账号')this.SettingRow('个人资料','头像、昵称和简介','去完善')this.SettingRow('登录设备','查看最近登录的手机和平板','2 台')this.SectionTitle('通知')this.SwitchRow('消息推送','订单和系统通知会及时提醒',this.pushEnabled,(value:boolean)=>{this.pushEnabled=value})this.SwitchRow('使用蜂窝网络同步','非 Wi-Fi 环境也同步草稿',this.useCellular,(value:boolean)=>{this.useCellular=value})}.padding(16).backgroundColor('#F5F7FA')}}

把关键代码一段段拆开

SectionTitle是最轻的 Builder,只接收一个标题。它把字号、颜色、间距固定住,后面设置页分组多了也不会样式漂移。

SettingRow负责普通可点击设置项。左侧是标题和说明,右侧是当前值和箭头。layoutWeight(1)让左侧说明占剩余空间,右侧值不会被长文案挤掉。

SwitchRow比普通行多一个开关状态和回调。这里没有让 Builder 自己保存状态,而是通过enabledonChange把状态交回页面。这样状态来源仍然清楚。

这三个 Builder 都只服务当前页面。如果以后多个页面都要用同样的设置行,再考虑抽成SettingRowComponent

Builder 不适合装太多业务

如果一个 UI 片段开始有自己的生命周期、网络请求、复杂状态,继续塞在@Builder里就不合适了。那时候它已经不是“局部模板”,而是一个真正的业务组件。

参数也别太多。一个 Builder 如果传了七八个参数,读调用处会很费劲。可以先合成一个配置对象,或者直接拆组件。

新手最容易踩的坑

这一类示例最容易让人产生错觉:界面出来了,就以为已经掌握了。其实真正容易出问题的地方,通常都在效果之外,比如状态有没有收拢、失败后怎么兜底、以后要扩展时会不会牵一发动全身。

所以你练这篇内容时,别只看“现在能不能跑”,还要继续看“以后好不好改”。能把这个习惯养起来,你写出来的页面会比单纯照着示例拼出来的页面稳很多。

放进真实项目还要补什么

示例代码的重点是把核心思路讲明白,所以很多工程化细节会故意省掉。真正落到项目里时,你通常还要继续补接口联动、异常处理、边界保护、资源抽离,以及和其他页面状态之间的配合。

写在最后

比较稳的做法是分三步走:先把结构和职责立住,再把真实业务接进去,最后再优化视觉和交互体验。这样改出来的页面不只是“能演示”,而是真的更接近可以长期维护的业务代码。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询