鸿蒙开发中的组件样式复用

2025-06-28 14:00:47
105次阅读
0个评论

本文基于HarmonyOSApi14。

在一个项目中,可以说页面数量通常是比较多的,而每个页面呢,又通常由众多的组件构成,每个组件有时还涉及了很多的属性设置,比如宽度、高度、背景样式等,无论是单个页面还是多个页面之间,都不可避免地会出现相同的组件,同时也会存在相同的样式属性。

针对这些重复出现的组件,我们可以通过单独自定义的方式实现组件复用,以此提高开发效率、减少重复代码。而对于那些相同的样式属性,为了使代码更加简洁、易于维护,同样有必要进行复用处理。

比如下面的代码:

Column() {
      Column() {
        Text("test 1")
          .fontColor(Color.White)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
      }
      .width("100%")
      .height(100)
      .backgroundColor(Color.Pink)
      .justifyContent(FlexAlign.Center)
      .margin({ top: 10 })

      Column() {
        Text("test 2")
          .fontColor(Color.White)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
      }
      .width("100%")
      .height(100)
      .backgroundColor(Color.Pink)
      .justifyContent(FlexAlign.Center)
      .margin({ top: 10 })

      Column() {
        Text("test 3")
          .fontColor(Color.White)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
      }
      .width("100%")
      .height(100)
      .backgroundColor(Color.Pink)
      .justifyContent(FlexAlign.Center)
      .margin({ top: 10 })

      Column() {
        Text("test 4")
          .fontColor(Color.White)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
      }
      .width("100%")
      .height(100)
      .backgroundColor(Color.Pink)
      .justifyContent(FlexAlign.Center)
      .margin({ top: 10 })
    }
  }

从以上的代码中可以看到,在 Column 组件内部嵌套了四个子Column组件,并且,这些子Column组件的样式属性完全一致,同时,每个子Column组件又都包含相同的Text组件,这些Text组件的样式也是一样的。

可以说在实际开发中,像这样大量重复的样式代码屡见不鲜,造成的结果就是,代码冗余不仅使得代码结构变得臃肿,还会给后续的代码维护工作带来很多的不便,极大的增加维护成本。

为了解决以上的问题,我们可以采取样式复用的方法,目前,主要有两种抽取方式可供选择,其一,是组件的抽取,我们可以直接使用 ForEach 循环对重复的组件进行遍历渲染,从而避免在代码中重复编写相同的组件结构,其二,是样式的抽取,通过将重复的样式属性提取出来,集中管理,然后在需要的地方进行引用,这样能够有效减少代码中的重复样式定义,使代码更加简洁、清晰,便于维护。

通用属性样式抽取

所谓的通用属性抽取,那就是所有组件的通用属性,比如组件的宽高,背景,内外边距等等,但是,有一点需要知道,那就是组件的自身属性不支持的,比如文本组件的颜色大小,图片的占位图等等,凡是自身组件的属性,通用样式都是不支持的;通用属性抽取,可以通过@Styles装饰器。

还是以上的案例,我们使用@Styles装饰器来抽取一下。

@Entry
@Component
struct Index {
  @Styles
  columnStyle() {
    .width("100%")
    .height(100)
    .backgroundColor(Color.Pink)
    .margin({ top: 10 })
  }

  build() {
    Column() {
      Column() {
        Text("我是组件一")
          .fontColor(Color.White)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
      }
      .columnStyle()
      .justifyContent(FlexAlign.Center)

      Column() {
        Text("我是组件二")
          .fontColor(Color.White)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
      }
      .columnStyle()
      .justifyContent(FlexAlign.Center)

      Column() {
        Text("我是组件三")
          .fontColor(Color.White)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
      }
      .columnStyle()
      .justifyContent(FlexAlign.Center)

      Column() {
        Text("我是组件四")
          .fontColor(Color.White)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
      }
      .columnStyle()
      .justifyContent(FlexAlign.Center)

    }
  }
}

可以看到Column组件经过抽取之后,还是十分简洁的,但是大家也看到了前边说的问题,那就是@Styles装饰器只支持通用的属性,由于justifyContent属性是Column组件自身的属性,所以不能进行设置,而Text组件里的属性也属于Text组件的自身属性,这里也无法进行使用。

以上的方式是在组件内抽取的,当然,@Styles装饰器也支持全局抽取的,你可以把它单独的抽取到一个页面之中,供所有的一样的组件样式进行复用。

@Styles
function columnStyle() {
  .width("100%")
    .height(100)
    .backgroundColor(Color.Pink)
    .margin({ top: 10 })
}

组件样式抽取

使用@Styles装饰器虽然解决了一定的代码冗余,但是还是不够彻底,毕竟很多的自身属性它是不支持的,为了解决以上的问题,我们可以使用@Extend装饰器。

还是以上的案例,我们进行抽取一下。

@Extend(Column)
function columnStyle() {
  .width("100%")
  .height(100)
  .backgroundColor(Color.Pink)
  .margin({ top: 10 })
  .justifyContent(FlexAlign.Center)
}

@Extend(Text)
function textStyle() {
  .fontColor(Color.White)
  .fontSize(16)
  .fontWeight(FontWeight.Bold)
}

@Entry
@Component
struct Index {
  build() {
    Column() {
      Column() {
        Text("我是组件一").textStyle()
      }.columnStyle()

      Column() {
        Text("我是组件二").textStyle()
      }.columnStyle()

      Column() {
        Text("我是组件三").textStyle()
      }.columnStyle()

      Column() {
        Text("我是组件四").textStyle()
      }.columnStyle()

    }
  }
}

是不是可以看到,使用@Extend装饰器,明显比@Styles装饰器简洁多的。

简单总结

@Styles装饰器和@Extend装饰器,在实际的开发中,都能解决我们样式属性冗余的问题,但是他们俩的用处确实不一样的,比如,如果相同组件的样式复用,我们就可以使用@Extend装饰器,如果不同组件的通用样式,我们则可以使用@Styles装饰器。

虽然说,以上的两个装饰器,可以解决我们样式冗余的问题,但是,我想要根据某个条件判断是否设置一个属性样式,也就是动态属性的设置,是不支持的,为了解决属性动态设置问题,就不得不提到鸿蒙当中的另一个可以抽取属性样式的方式,使用AttributeModifier,这个我们以后的文章中再做介绍。

文章标签:HarmonyOS语言,ArkUI

收藏00

登录 后评论。没有帐号? 注册 一个。