写点什么

鸿蒙应用开发从入门到实战(十九):样式复用案例

作者:程序员潘Sir
  • 2025-10-11
    四川
  • 本文字数:3086 字

    阅读完需:约 10 分钟

鸿蒙应用开发从入门到实战(十九):样式复用案例

大家好,我是潘 Sir,持续分享 IT 技术,帮你少走弯路。《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新 AI+编程、企业级项目实战等原创内容、欢迎关注!


上一篇文章讲解了 ArkUI 中样式复用思想,本节继续使用自定义组件对商品列表进行优化。


复习知识内容:


  • 创建自定义组件

  • @Builder

  • @Styles


在原来 pages/layout/ProductList.ets 基础上进行优化


一、自定义组件优化头部

实际项目开发中,存在多个界面共享顶部的情况。因此把顶部抽取出来作为自定义组件共用。


1.1 静态头部制作

拷贝 ic_public_back.png 和 ic_public_refresh.png 到 resources/base/media 目录


拷贝 pages/layout/list/ProductList.ets 文件,重命名为 ProductListLast.ets


(直接复制的文件,不会再 resources/base/profile/main_pages.json 文件中配置路由,需要手动设置:"pages/layout/list/ProductListLast",)


修改标题部分:


// 标题      Row() {        Image($r('app.media.ic_public_back'))          .width(30)
Text('商品列表') .fontSize(30) .fontWeight(FontWeight.Bold) Blank()
Image($r('app.media.ic_public_refresh')) .width(30) } .width('100%') // .height(30) //控制高度 .margin({ bottom: 20 })
复制代码


效果


1.2 头部抽取为组件

1.2.1 抽取到同一个文件中

// 自定义顶部组件@Componentstruct Header {  private title: ResourceStr
build() { // 标题 Row() { Image($r('app.media.ic_public_back')) .width(30)
Text(this.title) //从外层传入 .fontSize(30) .fontWeight(FontWeight.Bold)
Blank()
Image($r('app.media.ic_public_refresh')) .width(30) } .width('100%') // .height(30) //控制高度 // .margin({ bottom: 20 }) //放到外层控制 }}
复制代码


原来头部的内容替换为自定义组件使用


// 使用自定义组件      Header({ title: '商品列表' })      .margin({bottom:20})
复制代码


效果和原来一致。

1.2.2 单独抽取为一个文件

在 pages/component 目录新建 common 目录,新建 ArkTS File,名称为:CommonComponents.ets,并将自定义顶部组件代码粘贴进去,并通过 export 将组件导出。


// 自定义顶部组件@Componentexport struct Header {  private title: ResourceStr
build() { // 标题 Row() { Image($r('app.media.ic_public_back')) .width(30)
Text(this.title) //从外层传入 .fontSize(30) .fontWeight(FontWeight.Bold)
Blank()
Image($r('app.media.ic_public_refresh')) .width(30) } .width('100%') // .height(30) //控制高度 // .margin({ bottom: 20 }) //放到外层控制 }}
复制代码


回到 ProductListLast.ets 文件,导入自定义组件


// 导入自定义顶部组件import {Header} from '../../component/common/CommonComponents'
复制代码

二、自定义构建函数优化 UI 结构

以上代码中,可读性较差,可以把商品列表的部分封装起来,自定义组件或自定义构建函数都可以优化。

2.1 全局自定义构建函数

通过 @Builder 自定义构建函数,将商品卡片信息放置到函数中,函数定义在全局


// 全局自定义构建函数@Builder function ItemCard(item:Item2){  Row({ space: 10 }) {    Image(item.image)      .width(100)    Column({ space: 4 }) {      if (item.discount) {        Text(item.name)          .fontSize(20)          .fontWeight(FontWeight.Bold)        Text('原价:¥' + item.price)          .fontColor('#CCC')          .fontSize(14)          .decoration({ type: TextDecorationType.LineThrough })        Text('折扣价:¥' + (item.price - item.discount))          .fontColor('#F36')          .fontSize(18)        Text('补贴:¥' + item.discount)          .fontColor('#F36')          .fontSize(18)      } else {        Text(item.name)          .fontSize(20)          .fontWeight(FontWeight.Bold)        Text('¥' + item.price)          .fontColor('#F36')          .fontSize(18)      }    }    .height('100%')    .alignItems(HorizontalAlign.Start)  }  .width('100%')  .backgroundColor('#FFF')  .borderRadius(20)  .height(120)  .padding(10)}
复制代码


将原有线上组件的地方替换为函数调用


ItemCard(item)
复制代码


这样,界面效果不变,但是代码更简洁,可读性更高。

2.2 局部自定义构建函数

函数定义在组件内部,将以上组件代码拷贝,并去掉 function 关键字


// 局部自定义构建函数 不要function关键字  @Builder  ItemCard(item:Item2){  Row({ space: 10 }) {    Image(item.image)      .width(100)    Column({ space: 4 }) {      if (item.discount) {        Text(item.name)          .fontSize(20)          .fontWeight(FontWeight.Bold)        Text('原价:¥' + item.price)          .fontColor('#CCC')          .fontSize(14)          .decoration({ type: TextDecorationType.LineThrough })        Text('折扣价:¥' + (item.price - item.discount))          .fontColor('#F36')          .fontSize(18)        Text('补贴:¥' + item.discount)          .fontColor('#F36')          .fontSize(18)      } else {        Text(item.name)          .fontSize(20)          .fontWeight(FontWeight.Bold)        Text('¥' + item.price)          .fontColor('#F36')          .fontSize(18)      }    }    .height('100%')    .alignItems(HorizontalAlign.Start)  }  .width('100%')  .backgroundColor('#FFF')  .borderRadius(20)  .height(120)  .padding(10)}
复制代码


在原来商品列表处进行调用,条用局部自定义组件,需要使用 this 关键字


this.ItemCard(item) //局部组件使用
复制代码

三、自定义样式装饰器优化样式

3.1 容器全局样式

将 Column 的通用样式抽取到自定义样式函数 fillScreen 中


将 fillScreen 放到组件外


// 自定义全局公共样式@Styles function fillScreen(){  .width('100%')  .height('100%')  .backgroundColor('#EFEFEF')  .padding(20)}
复制代码


使用


Column({ space: 8 }){...}// 自定义样式.fillScreen()
复制代码

3.2 容器局部样式

将 fillScreen 放到组件内,去掉 function 关键字


// 自定义局部公共样式  @Styles  fillScreen(){    .width('100%')    .height('100%')    .backgroundColor('#EFEFEF')    .padding(20)  }
复制代码


使用方式不变,抽取后预览效果一致。

3.3 商品信息样式抽取

将商品信息样式中的价格样式抽取到公共全局样式中,由于 fontColor 和 fontSize 是 Text 专有的,不是公共样式,因此使用 @Styles 会报错,应该使用 Extend(Text),并且 Textend 只能写在全局。


// 自定义全局价格样式// @Styles function priceText(){@Extend(Text) function priceText(){  //Extend继承模式不能写在组件内,只能写在全局  .fontColor('#F36')  .fontSize(18)}
复制代码


将原来的样式方法改为自定义方法即可


// .fontColor('#F36')// .fontSize(18).priceText()
复制代码


这样,不仅代码层次更清晰,还可以更方便的维护和修改,只需要修改公共样式,其它引用的地方就可以直接被修改。


《鸿蒙应用开发从入门到项目实战》系列文章持续更新中,陆续更新 AI+编程、企业级项目实战等原创内容,防止迷路,欢迎关注!

发布于: 刚刚阅读数: 4
用户头像

网名:黑马腾云 2020-06-22 加入

80后创业者、高级架构师,带你轻松学编程!著有《Node.js全栈开发从入门到项目实战》、《Java企业级软件开发》、《HarmonyOS应用开发实战》等书籍。“自学帮”公众号主。

评论

发布
暂无评论
鸿蒙应用开发从入门到实战(十九):样式复用案例_鸿蒙_程序员潘Sir_InfoQ写作社区