HarmonyOS NEXT⚡️样式封装快快看

1,605 阅读3分钟

image.png

如何选择HarmonyOS NEXT中的样式封装

本文将详细列出ArkUI中支持样式封装的各种方式,逐一分析它们的优点和不足之处。每种方式都会结合实际示例进行说明,以便更好地理解和应用这些样式封装方法。通过对比和具体例子的讲解,希望能够帮助开发者选择最适合自己项目的样式封装方式,提高开发效率和代码的可维护性。

封装方式对比

方式支持传入参数支持export支持组件内定义
@Styles
@Extend
attributeModifier

封装方式列举

ArkUi 提供了多种样式封装的方式,包括 @Styles @Extend attributeModifier

1. @Styles

如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,我们推出了可以提炼公共样式进行复用的装饰器@Styles。 @Styles装饰器可以将多条样式设置提炼成一个方法,直接在组件声明的位置调用。通过@Styles装饰器可以快速定义并复用自定义样式。用于快速定义并复用自定义样式。

import TitleText from '../components/TitleText';
@Styles function CardStyle() {
  .width('90%')
  .backgroundColor(Color.White)
  .borderRadius('15vp')
  .padding('10vp')
}

@Component
export default struct MinePage {
  @State message: string = 'MINE';
  build() {
    GridRow({
      columns: {
        sm: 4,
        md: 8,
        lg: 12,
      },
      gutter: {
        x: 12
      }
    }) {
      GridCol({
        span: {
          sm: 4,
          md: 6,
          lg: 8
        },
        offset: {
          md: 1,
          lg: 2
        }
      }) {
        Column() {
          TitleText({title:'我的',fsize:20})
            .margin({bottom:'20vp'})
          HeaderInfo()
          Text('测试')
            .margin(20)
            .CardStyle()
        }
        .height('100%')
      }
    }
    .backgroundColor('#f2f3f5')
    .padding('10vp')
  }
}

@Component
@Preview
struct HeaderInfo {
  build() {
    Row() {
      Image($r('app.media.touxiang'))
        .width('50vp')
        .height('50vp')
        .borderRadius('25vp')
        .margin('10vp')
      Column({space:5}) {
        Text('Justkang')
          .fontSize('20vp')
        Text('Justkang@huawei.com')
          .fontSize('14vp')
          .fontColor(Color.Blue)
      }
      .alignItems(HorizontalAlign.Start)
    }
    .CardStyle()
  }
}

代码解读:

首先我们在etc中使用@Stytle修饰器 把卡片的样式提取出来,然后在组件内使用.fn()的方式调用。

效果

image.png

2. @Extend

@Extend用于拓展原生组件样式,可以进行传值。

@Extend(Text) function TextColorSize (color: Color,size: string) {
  .fontColor(color)
  .fontSize(size)
}

@Component
export default struct MinePage {
  @State message: string = 'MINE';
  build() {
    GridRow({
      columns: {
        sm: 4,
        md: 8,
        lg: 12,
      },
      gutter: {
        x: 12
      }
    }) {
      GridCol({
        span: {
          sm: 4,
          md: 6,
          lg: 8
        },
        offset: {
          md: 1,
          lg: 2
        }
      }) {
        Column() {
          TitleText({title:'我的',fsize:20})
            .margin({bottom:'20vp'})
          HeaderInfo()
          Text('测试1')
            .margin(20)
            .CardStyle()
            .TextColorSize(Color.Red,'20vp')
          Text('测试2')
            .margin(20)
            .CardStyle()
            .TextColorSize(Color.Yellow,'16vp')
          Text('测试3')
            .margin(20)
            .CardStyle()
            .TextColorSize(Color.Green,'12vp')
        }
        .height('100%')
      }
    }
    .backgroundColor('#f2f3f5')
    .padding('10vp')
  }
}

代码解读

首先我们在ets文件中定义了一个@Extend()装饰器,并且传入了Text组件。意味着这是个拓展Text样式的组件。并且接收color,size 两个参数。使用的时候用.fn(...arg) 方式。

效果

image.png

3. attributeModifier

动态设置组件的属性方法

applyNormalAttributeapplyPressedAttributeapplyFocusedAttributeapplyDisabledAttributeapplySelectedAttribute
组件普通状态时的样式组件按压状态的样式组件获焦状态的样式组件禁用状态的样式组件选中状态的样式
class CardStyleModifier implements AttributeModifier<CommonAttribute> {
  myColor:Color = Color.Black
  applyNormalAttribute(instance: CommonAttribute): void {
    instance.width('90%')
    instance.backgroundColor(Color.White)
    instance.borderRadius('15vp')
    instance.padding('10vp')
    instance.border({
      width: '2vp',
      color: this.myColor,
      style: BorderStyle.Solid
    })
  }
  setBorderColor(color: Color) {
    this.myColor = color
  }
}

@Component
@Preview
struct HeaderInfo {
  @State cardModifier:CardStyleModifier = new CardStyleModifier()
  build() {
    Row() {
      Image($r('app.media.touxiang'))
        .width('50vp')
        .height('50vp')
        .borderRadius('25vp')
        .margin('10vp')
      Column({space:5}) {
        Text('Justkang')
          .fontSize('20vp')
          .attributeModifier(this.cardModifier)
        Text('Justkang@huawei.com')
          .fontSize('14vp')
          .fontColor(Color.Blue)
      }
      .alignItems(HorizontalAlign.Start)
    }
    .attributeModifier(this.cardModifier)
    .onClick(() => {
      this.cardModifier.setBorderColor(Color.Blue)
    })
  }
}

代码解读

定义好CardStyleModifier之后,我们需要在使用的时候new一下,然后.attributeModifier(this.cardModifier)的方式使用。

注意事项

同一个modifier属性会共享,如果两个组件使用同一个modifier,并且修改了其中的属性,那么改一个全都改。

效果

1.mov.gif

解决方法

@State cardModifier:CardStyleModifier = new CardStyleModifier()
@State cardModifier2:CardStyleModifier = new CardStyleModifier()

结论

在本文中,我们详细探讨了ArkUI中的三种主要样式封装方式:@Styles、@Extend 和 attributeModifier。

每种方法都有其独特的优点和适用场景:

  • @Styles 适用于复用简单的公共样式,增强代码的简洁性和可维护性。
  • @Extend 允许在组件上扩展样式并传入参数,适合需要动态样式的场景。
  • attributeModifier 提供了更高级的动态样式控制,可以根据不同状态调整组件属性,适合复杂的交互场景。 通过结合这些方法,开发者可以根据实际需求选择最合适的样式封装方式,从而提升开发效率和代码质量。 希望本文的讲解和示例能帮助你更好地理解和应用这些样式封装方式。

如果你有任何疑问或建议,欢迎在评论区交流。