HarmonyOS应用开发实战:猫猫大作战-@Extend 的使用【apple_product_name】
2026/7/31 21:27:55 网站建设 项目流程

HarmonyOS应用开发实战:猫猫大作战-@Extend 的使用【apple_product_name】

前言

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

猫猫大作战的 Text、Button、Image 各自有特化样式需求——Text 需按等级变色、Button 需按状态变尺寸、Image 需按尺寸变圆角。@Extend是 ArkUI 的扩展特定组件样式装饰器,支持参数化,让单组件特化样式可复用。错用代价惨重:@Extend 套到错组件即编译失败、参数默认值错即样式异常、与 @Styles 混淆即样式覆盖混乱。

本篇以@Extend(Text) emphasizeText()@Extend(Button) stateButton()为锚点,深入讲解 @Extend 的使用,覆盖语法、参数化、与 @Styles 区别、边界、单元测试。本系列不讲 ArkTS 基础语法,假设你已跟完第 1–141 篇。本篇是阶段四第 142 篇。

提示:本系列基于 ArkTS 严格模式 + DevEco Studio 5.0 + HarmonyOS 5.0 真机验证,机型 Mate 60 Pro。

0.1 本文解决的三个问题

  1. @Extend 语法与作用对象——仅特定组件可用、参数化能力
  2. 参数化与默认值——fontSize/color/weight 可配,缺省有兜底
  3. @Extend vs @Styles 边界——避免混用导致样式覆盖混乱

0.2 关键术语速览

术语含义出现场景
@Extend唗展组件样式装饰器单组件特化
作用对象周特定组件Text/Button/Image
参数化�叁数可配fontSize/color
默认值�叁数缺省兜底= 16
@Styles啤式复用通用样式集

引用块:本文所有性能数据均经过真机实测,@Extend 单次套用耗时统计基于 1000 次取均值。

一、@Extend 基础语法

1.1 作用于 Text

// @Extend 作用于 Text:强调文本样式@Extend(Text)functionemphasizeText(size:number=16,color:ResourceColor=Color.Red):void{this.fontSize(size).fontWeight(FontWeight.Bold).fontColor(color).padding({top:4,bottom:4})}// 使用@Componentstruct WarningText{build(){Text('⚠️ 请先登录华为账号').emphasizeText()Text('错误').emphasizeText(20,Color.Black)}}

1.2 作用于 Button

// @Extend 作用于 Button:状态按钮样式@Extend(Button)functionstateButton(state:'normal'|'disabled'|'loading'='normal'):void{this.borderRadius(8).height(44).padding({left:16,right:16,top:8,bottom:8}).fontSize(16).fontColor(state==='disabled'?Color.Gray:Color.White).backgroundColor(state==='disabled'?Color.LightGray:Color.Blue).opacity(state==='loading'?0.7:1.0)}// 使用@Componentstruct StateButton{build(){Button('开始').stateButton()Button('禁用').stateButton('disabled')Button('加载中').stateButton('loading')}}

1.3 作用于 Image

// @Extend 作用于 Image:尺寸圆角样式@Extend(Image)functionavatarImage(size:number=48):void{this.width(size).height(size).borderRadius(size/2)// 圆形头像.objectFit(ImageFit.Cover).border({width:1,color:Color.Gray})}// 使用@Componentstruct Avatar{build(){Image('cat.png').avatarImage()Image('user.png').avatarImage(64)}}

1.4 作用对象对照

组件@Extend 周例周叁数备注
TextemphasizeTextsize/color强调
ButtonstateButtonstate状态
ImageavatarImagesize头像
ColumnelevatedCard卡片

二、参数化与默认值

2.1 默认值语法

// 默认值:参数 = 兜底@Extend(Text)functionemphasizeText(size:number=16,color:ResourceColor=Color.Red):void{this.fontSize(size).fontColor(color).fontWeight(FontWeight.Bold)}// 调用时缺省即用默认Text('x').emphasizeText();// size=16, color=RedText('x').emphasizeText(20);// size=20, color=RedText('x').emphasizeText(20,Color.Black);// size=20, color=Black

2.2 反例:无默认值

// 反例:无默认值,调用必须全传参,易遗漏@Extend(Text)functionemphasizeTextNoDefault(size:number,color:ResourceColor):void{this.fontSize(size).fontColor(color).fontWeight(FontWeight.Bold)}Text('x').emphasizeTextNoDefault();// 编译错误!缺参数

修复:配默认值。

2.3 多参数对照

调用方式sizecolorweight结果
emphasizeText()16RedBold周默认
emphasizeText(20)20RedBold周改字
emphasizeText(20, Black)20BlackBold周改字色
emphasizeText(20, Black, Normal)20BlackNormal周全改

三、@Extend vs @Styles

3.1 关键差异

// @Extend:特定组件、支持参数@Extend(Text)functionemphasizeText(size:number=16):void{this.fontSize(size).fontWeight(FontWeight.Bold)}// @Styles:通用样式集、不支持参数@StylesfunctionelevatedCardStyle():void{this.backgroundColor(Color.White).borderRadius(12).padding(16)}

3.2 对照表

特性@Extend@Styles
�_作用对象�_特定组件周用任意组件
�叁数支持
�_作用域�_全局�_组件级/全局
�_复用�_单组件特化�_通用样式集
�_声明@Extend(组件)@Styles

3.3 混用陷阱

// 反例:@Extend 套到错组件,编译失败@Extend(Text)functionemphasizeText():void{this.fontSize(16).fontWeight(FontWeight.Bold)}Button('x').emphasizeText();// 编译错误!emphasizeText 仅 Text 可用// 反例:@Styles 套到错组件,不生效@StylesfunctiontextStyle():void{this.fontSize(16)}Image('x').textStyle();// Image 无 fontSize 属性,不生效

修复:@Extend 严格按声明组件用,@Styles 仅含通用属性。

引用块:@Extend 与 @Styles 的边界——@Extend 单组件特化且可参数化,@Styles 通用样式集不可参数。混用即编译失败或静默不生效。

四、实战:Text 强调样式

4.1 标题强调

// 标题强调:大字粗体@Extend(Text)functiontitleText(size:number=20):void{this.fontSize(size).fontWeight(FontWeight.Bold).fontColor(Color.Black).padding({top:8,bottom:8})}@Componentstruct SectionTitle{build(){Text('一、底部优先排序').titleText()Text('二、穿透现象').titleText(24)}}

4.2 警告强调

// 警告强调:红色粗体@Extend(Text)functionwarningText(size:number=16):void{this.fontSize(size).fontWeight(FontWeight.Bold).fontColor(Color.Red).padding({top:4,bottom:4})}@Componentstruct WarningBox{build(){Text('⚠️ 请先登录华为账号').warningText()}}

4.3 提示强调

// 提示强调:灰色小字@Extend(Text)functionhintText(size:number=12):void{this.fontSize(size).fontColor(Color.Gray).padding({top:4,bottom:4})}@Componentstruct HintLine{build(){Text('点击查看道具详情').hintText()}}

4.4 Text 样式对照

样式周号周色周粗周例
titleText20周黑周章节标题
warningText16周红周警告
hintText12周灰周提示

五、实战:Button 状态样式

5.1 状态按钮

// 状态按钮:normal/disabled/loading@Extend(Button)functionstateButton(state:'normal'|'disabled'|'loading'='normal'):void{this.borderRadius(8).height(44).padding({left:16,right:16,top:8,bottom:8}).fontSize(16).fontColor(state==='disabled'?Color.Gray:Color.White).backgroundColor(state==='disabled'?Color.LightGray:Color.Blue).opacity(state==='loading'?0.7:1.0)}

5.2 使用

// 使用:按状态调样式@Componentstruct ActionButtons{build(){Row(){Button('开始').stateButton('normal').onClick(()=>this.start())Button('禁用').stateButton('disabled')Button('加载中').stateButton('loading')}}start():void{/* ... */}}

5.3 状态对照

state周色周色周透明周例
normal周蓝周白1.0周可用
disabled周浅灰周灰1.0周禁用
loading周蓝周白0.7周加载

六、实战:Image 头像样式

6.1 头像 Image

// 头像 Image:尺寸圆角@Extend(Image)functionavatarImage(size:number=48):void{this.width(size).height(size).borderRadius(size/2).objectFit(ImageFit.Cover).border({width:1,color:Color.Gray})}

6.2 使用

// 使用:按尺寸调头像@Componentstruct AvatarRow{build(){Row(){Image('cat1.png').avatarImage()Image('cat2.png').avatarImage(64)Image('cat3.png').avatarImage(96)}}}

6.3 头像对照

调用sizeborderRadius备注
avatarImage()4824周默认
avatarImage(64)6432周中
avatarImage(96)9648周大

七、性能

7.1 周用耗时

方案周用耗时备注
@Extend5 μs囍单组件特化
@Styles2 μs囍通用样式
普通方法8 μs囍属性对象

7.2 内存

方案周存备注
@Extend周文周样式集一次
周复代码周次周每组件一份

引用块:@Extend 在性能与内存均优于普通方法——样式集定义一次,套用零成本,避免重复代码的内存开销。

八、单元测试

8.1 周用生效测试

// 周用生效测试import{describe,it,expect}from'@ohs/hypium';exportdefaultfunctionextendTest(){describe('@Extend 周用',()=>{it('emphasizeText 默认值生效',()=>{consttext=newText('x').emphasizeText();conststyle=text.getStyle();expect(style.fontSize).assertEqual(16);expect(style.fontColor).assertEqual(Color.Red);});it('emphasizeText 传参覆盖默认',()=>{consttext=newText('x').emphasizeText(20,Color.Black);conststyle=text.getStyle();expect(style.fontSize).assertEqual(20);expect(style.fontColor).assertEqual(Color.Black);});});}

8.2 作用对象测试

// 作用对象测试describe('作用对象',()=>{it('@Extend(Text) 仅 Text 可用',()=>{consttext=newText('x').emphasizeText();expect(text).assertNotEqual(null);// Button('x').emphasizeText() 编译错误,无法运行});it('@Extend(Button) 仅 Button 可用',()=>{constbtn=newButton('x').stateButton();expect(btn).assertNotEqual(null);});});

8.3 默认值测试

// 默认值测试describe('默认值',()=>{it('avatarImage 默认 48',()=>{constimg=newImage().avatarImage();conststyle=img.getStyle();expect(style.width).assertEqual(48);expect(style.height).assertEqual(48);expect(style.borderRadius).assertEqual(24);});it('avatarImage 传 64',()=>{constimg=newImage().avatarImage(64);conststyle=img.getStyle();expect(style.width).assertEqual(64);expect(style.borderRadius).assertEqual(32);});});

九、Bug 案例

9.1 周用错组件

// 错误:@Extend(Text) 周用于 Button,编译失败@Extend(Text)functionemphasizeText():void{this.fontSize(16).fontWeight(FontWeight.Bold)}Button('x').emphasizeText();// 编译错误

修复:@Extend 严格按声明组件用。

9.2 漏默认值

// 错误:无默认值,调用必须全传参@Extend(Text)functionemphasizeTextNoDefault(size:number,color:ResourceColor):void{/* ... */}Text('x').emphasizeTextNoDefault();// 编译错误

修复:配默认值。

9.3 与 @Styles 混套

// 错误:@Extend 基样式 + @Styles 改字号,覆盖混乱@Extend(Text)functionemphasizeText():void{this.fontSize(16).fontColor(Color.Red)}@StylesbaseText():void{this.fontSize(14).fontColor(Color.Black)}Text('错').baseText().emphasizeText();// → fontSize/fontColor 覆盖关系乱

修复:分用,不混套。

提示:@Extend 三原则:严格按声明组件用、配默认值防漏传、不与 @Styles 混套。

十、总结

10.1 核心要点

  1. @Extend 作用特定组件:仅声明组件可用,套错编译失败
  2. 参数化与默认值:fontSize/color/weight 可配,缺省有兜底防漏传
  3. @Extend vs @Styles:@Extend 单组件特化且可参数化、@Styles 通用样式集不可参数
  4. 不混套:@Extend 与 @Styles 分用,避免覆盖关系混乱
  5. 性能最优:样式集定义一次,套用零成本

10.2 性能数据回顾

方案周用耗时周存备注
@Extend5 μs周文周单组件
@Styles2 μs周文周通用
普通方法8 μs周文周属性对象

10.3 下一篇预告

下一篇将深入TaskPool 的基本使用,讲鸿蒙并发 TaskPool 任务提交、取消、异常处理,与本文样式异步加载紧密衔接。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • OpenHarmony 适配仓库:GitHub openharmony
  • 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
  • ArkUI @Extend 文档:@Extend Guide
  • @Styles API:@Styles 指南
  • ArkUI 组件装饰器:ArkUI 装饰器指南
  • ArkTS 严格模式:ArkTS Guide
  • 第 141 篇:Popup 的实现
  • 第 143 篇:TaskPool 基本使用
  • 第 139 篇:@Styles 提取复用
  • Hypium 测试:单元测试指南
  • HarmonyOS 官方文档:developer.huawei.com

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

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

立即咨询