
文章目录什么时候该用 Builder导航 Tab 是最直观的例子Builder 和组件怎么取舍页面结构怎么看完整代码写在最后页面写到一定规模后build()里最容易变成一大坨。导航项、统计卡片、文章卡片这些结构一重复后面改样式会非常痛苦。这个 HarmonyOS7 案例用Builder把几个 UI 片段抽出来。它不是为了炫语法而是让重复结构有一个固定入口后面改起来不至于满页面找代码。什么时候该用 Builder我一般看两个条件结构会重复这段结构还不值得单独拆成一个组件。比如导航 Tab、统计卡片、文章卡片就很合适。代码里定义了NavItem_w4f0和StatCard_6l41再通过NavTabItem()、StatCardItem()、ArticleCard()把 UI 片段封起来。这样build()里只负责组织页面而不是塞满每个卡片的细节。导航 Tab 是最直观的例子NavTabItem()接收一个导航数据和选中状态然后处理图标、徽标、文字颜色和点击事件。选中态只通过isSelected控制逻辑非常集中。NavTabItem(item:NavItem_w4f0,isSelected:boolean){Column({space:4}){Stack({alignContent:Alignment.TopEnd}){Text(item.icon).fontSize(20)if(item.badge0){Text(item.badge.toString()).fontSize(9).fontColor(Color.White).backgroundColor(#EF4444).borderRadius(7).width(14).height(14).textAlign(TextAlign.Center).offset({x:6,y:-6})}}.width(32).height(32)Text(item.label).fontSize(12).fontColor(isSelected?#2563EB:#9CA3AF).fontWeight(isSelected?FontWeight.Bold:FontWeight.Normal)}.width(80).alignItems(HorizontalAlign.Center).padding({top:6,bottom:6}).onClick((){this.selectedNavitem.id})}如果不抽出来导航项有 4 个就会复制 4 份结构。以后要改徽标位置或字体颜色很容易漏改。Builder 和组件怎么取舍Builder更轻适合当前页面内部复用组件更独立适合跨页面复用或有独立生命周期的 UI。这个案例里的卡片都属于页面内复用所以用Builder刚刚好。如果后面文章卡片要在首页、详情页、收藏页都用那就应该考虑拆成单独组件。页面结构怎么看BuilderArticleLayoutPage主要有导航 Tab、统计卡片、文章卡片三块。读代码时先看三个Builder方法再回到build()看它们如何被调用。这样比从头读完整页面轻松很多。完整代码下面是完整代码。入口组件名是BuilderArticleLayoutPage适合作为 HarmonyOS7 页面内 UI 片段复用的参考。// Builder 自定义构建函数interfaceNavItem_w4f0{id:numberlabel:stringicon:stringbadge:number}interfaceStatCard_6l41{id:numberlabel:stringvalue:stringunit:stringtrend:stringtrendUp:booleancolor:stringbgColor:stringicon:string}EntryComponentstruct BuilderArticleLayoutPage{StateselectedNav:number0StatelikeStates:boolean[][false,false,false]StatelikeCounts:number[][128,256,64]privatenavItems:NavItem_w4f0[][{id:0,label:推荐,icon:,badge:0},{id:1,label:关注,icon:,badge:3},{id:2,label:热榜,icon:,badge:0},{id:3,label:本地,icon:,badge:0},]privatestats:StatCard_6l41[][{id:1,label:今日销售,value:12,580,unit:元,trend:15.3%,trendUp:true,color:#2563EB,bgColor:#EFF6FF,icon:},{id:2,label:新增用户,value:347,unit:人,trend:8.7%,trendUp:true,color:#059669,bgColor:#ECFDF5,icon:},{id:3,label:退款率,value:2.1,unit:%,trend:-0.3%,trendUp:false,color:#EF4444,bgColor:#FEF2F2,icon:↩️},{id:4,label:订单量,value:1,024,unit:单,trend:22.1%,trendUp:true,color:#D97706,bgColor:#FFFBEB,icon:},]// Builder导航Tab项BuilderNavTabItem(item:NavItem_w4f0,isSelected:boolean){Column({space:4}){Stack({alignContent:Alignment.TopEnd}){Text(item.icon).fontSize(20)if(item.badge0){Text(item.badge.toString()).fontSize(9).fontColor(Color.White).backgroundColor(#EF4444).borderRadius(7).width(14).height(14).textAlign(TextAlign.Center).offset({x:6,y:-6})}}.width(32).height(32)Text(item.label).fontSize(12).fontColor(isSelected?#2563EB:#9CA3AF).fontWeight(isSelected?FontWeight.Bold:FontWeight.Normal)}.width(80).alignItems(HorizontalAlign.Center).padding({top:6,bottom:6}).onClick((){this.selectedNavitem.id})}// Builder统计卡片BuilderStatCardItem(card:StatCard_6l41){Column({space:8}){Row(){Text(card.icon).fontSize(20)Blank()Text(card.trend).fontSize(11).fontColor(card.trendUp?#059669:#EF4444).backgroundColor(card.trendUp?#D1FAE5:#FEE2E2).padding({left:6,right:6,top:2,bottom:2}).borderRadius(8)}.width(100%)Column({space:2}){Row({space:2}){Text(card.value).fontSize(22).fontWeight(FontWeight.Bold).fontColor(card.color)Text(card.unit).fontSize(12).fontColor(#9CA3AF).margin({top:6})}.alignItems(VerticalAlign.Bottom)Text(card.label).fontSize(12).fontColor(#6B7280)}.alignItems(HorizontalAlign.Start).width(100%)}.width(47%).padding(14).backgroundColor(card.bgColor).borderRadius(12)}// Builder文章卡片BuilderArticleCard(title:string,desc:string,author:string,idx:number){Column({space:10}){Row({space:8}){Text(author.substring(0,1)).fontSize(14).fontWeight(FontWeight.Bold).fontColor(Color.White).width(32).height(32).textAlign(TextAlign.Center).backgroundColor(#2563EB).borderRadius(16)Text(author).fontSize(13).fontColor(#374151).fontWeight(FontWeight.Medium).layoutWeight(1)Text(关注).fontSize(12).fontColor(#2563EB).backgroundColor(#EFF6FF).padding({left:10,right:10,top:4,bottom:4}).borderRadius(12)}.width(100%).alignItems(VerticalAlign.Center)Text(title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(#111827)Text(desc).fontSize(13).fontColor(#6B7280).lineHeight(20).maxLines(2).textOverflow({overflow:TextOverflow.Ellipsis})Row({space:16}){Row({space:4}){Text(this.likeStates[idx]?❤️:).fontSize(16)Text(this.likeCounts[idx].toString()).fontSize(12).fontColor(#9CA3AF)}.onClick((){this.likeStates[idx]!this.likeStates[idx]this.likeCounts[idx]this.likeStates[idx]?1:-1})Row({space:4}){Text().fontSize(16)Text(42).fontSize(12).fontColor(#9CA3AF)}Row({space:4}){Text().fontSize(16)Text(分享).fontSize(12).fontColor(#9CA3AF)}Blank()Text(...).fontSize(18).fontColor(#9CA3AF)}.width(100%).alignItems(VerticalAlign.Center)}.width(100%).padding(16).backgroundColor(Color.White).borderRadius(12)}build(){Column({space:0}){// 顶部标题Text(Builder 构建函数).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#111827).width(100%).padding({left:20,right:20,top:20,bottom:4})Text(抽取可复用的 UI 构建片段减少代码冗余).fontSize(13).fontColor(#6B7280).width(100%).padding({left:20,right:20,bottom:12})// 一、导航栏Builder NavTabItemColumn({space:8}){Text(一、Builder 导航Tab).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#374151).width(100%)Row(){ForEach(this.navItems,(item:NavItem_w4f0){this.NavTabItem(item,this.selectedNavitem.id)},(item:NavItem_w4f0)item.id.toString())}.width(100%).justifyContent(FlexAlign.SpaceAround).backgroundColor(Color.White).borderRadius(12).padding({top:4,bottom:4}).shadow({radius:6,color:rgba(0,0,0,0.06),offsetY:2})}.width(100%).padding({left:20,right:20}).alignItems(HorizontalAlign.Start).margin({bottom:16})// 二、统计卡片网格Builder StatCardItemColumn({space:10}){Text(二、Builder 统计卡片).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#374151).width(100%)Flex({wrap:FlexWrap.Wrap,justifyContent:FlexAlign.SpaceBetween}){ForEach(this.stats,(card:StatCard_6l41){this.StatCardItem(card)},(card:StatCard_6l41)card.id.toString())}}.width(100%).padding({left:20,right:20}).alignItems(HorizontalAlign.Start).margin({bottom:16})// 三、文章卡片列表Builder ArticleCardColumn({space:10}){Text(三、Builder 文章卡片).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#374151).width(100%)Column({space:8}){this.ArticleCard(HarmonyOS ArkUI 布局系统完全指南,深入讲解 Column、Row、Flex、Stack、RelativeContainer 五大布局组件的核心属性与实战技巧。,鸿蒙学堂,0)this.ArticleCard(State 状态装饰器驱动 UI 自动更新,详解 State、Prop、Link、Observed 等各种状态装饰器的使用场景和注意事项。,ArkDev,1)this.ArticleCard(从零构建 HarmonyOS 完整应用,手把手带你完成一个包含登录、首页、个人中心的完整鸿蒙应用涵盖路由、状态、网络请求。,开发者周刊,2)}}.width(100%).padding({left:20,right:20}).alignItems(HorizontalAlign.Start).margin({bottom:24})}.width(100%).height(100%).backgroundColor(#F9FAFB)}}写在最后如果你正在整理 HarmonyOS7 组件案例可以把这篇当成Builder的实践模板。先跑通页面再逐步替换数据和样式效率会高不少。