Harmony应用开发基础-装饰器-篇1

173 阅读3分钟

ArkTS的 UI范式装饰器 和 状态管理装饰器

1 UI范式装饰器

1.1 @Styles:组件样式的重用

​ 对于不同组件相同样式、事件统一抽取,然后复用,提高代码简洁性和方便后续维护。

@Styles分为全局定义和局部定义

定义为全局时,在方法名前添加function关键字

//定义全局的@Styles封装样式
@Styles
function globalFancy() {
  .width(200)
  .height(100)
  .backgroundColor(Color.Pink)
}

@Entry
@Component
struct Index {
  @State bgColor: ResourceColor = Color.Pink

  //定义组件内的@Styles封装样式
  @Styles
  fancy(){
    .width(180)
    .height(60)
    .backgroundColor(this.bgColor)
    .onClick(() => {
      this.bgColor = Color.Red
    })
  }

  build() {
    Column({ space: 10 }) {
      //使用全局@Styles
      Text("全局@Styles")
        .fontSize(20)
        .globalFancy()//通过 .函数名() 方式复用
      //使用组件内@Styles
      Text("组件内@Styles")
        .fontSize(20)
        .fancy()

    }
    .width("100%")
  }
}

image-20240819142541472.png

说明:

​ a.@Styles只支持通用属性通用事件的抽取

​ b.组件内@Styles的优先级高于全局@Styles

​ c.函数不支持传参!!

1.2 @Extend:特定组件样式的重用

​ 对于同一组件的样式、事件,统一抽取,减少代码量,增强可读性。

@Extend只有全局定义

@Extend(Text)
function fancy(fSize: number, fColor: ResourceColor, bgColor: ResourceColor) {
  .fontSize(fSize)
  .fontColor(fColor)
  .backgroundColor(bgColor)
}

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text("@Extend重用")
        .fancy(20, Color.Blue, Color.Red)
      Text("@Extend重用")
        .fancy(30, Color.White, Color.Green)
      Text("@Extend重用")
        .fancy(40, Color.Red, Color.Blue)
    }.width("100%")
  }
} 

image-20240819145533300.png

说明:

​ a.使用@Extend()时,在括号里加上要修饰的组件

​ b.只支持原生组件样式扩展

​ c.函数支持传参

1.3 @Builder:UI结构的重用

​ 将重复使用的UI元素抽象成一个方法,在build方法里调用。@Builder装饰的函数也称为“自定义构建函数”。

@Builder分为全局定义和局部定义

语法:

//1 全局定义
@Builder globalBuilder(){}
@Entry
@Component
struct Index {
  //2 局部定义
  @Builder MyBuilder(){}
  build() {
  	Column(){
        //1
        globalBuilder()
        //2
    	this.MyBuilder()
    }

  }
}

说明:

​ a.可传递参数

​ b.局部定义通过 .函数名() 方式复用

​ c.静态页面@Builder复用可传递多个参数,但如果要动态刷新页面,参数传递会有一些限制:

1.3.1 传参规则

  • 参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。

  • @Builder修饰的函数内部,不允许改变参数值。

  • @Builder内UI语法遵循UI语法规则

  • @Builder通过按引用传递的方式传入参数,才会触发动态渲染UI,并且参数只能是一个

  • @Builder如果传入的参数是两个或两个以上,不会触发动态渲染UI。

  • @Builder传入的参数中同时包含按值传递和按引用传递两种方式,不会触发动态渲染UI。

  • @Builder的参数必须按照对象字面量的形式,把所需要的属性一一传入,才会触发动态渲染UI。

tips:

对象字面量:一种创建对象的简便语法。它通过一对花括号 {} 包含一组以逗号分隔的键值对,每个键值对由一个属性名和一个属性值组成。语法示例如下:

const obj = {  
  name: "Alice",  
  age: 25,  
  isStudent: false  
}

1.3.2 传参方式

按值传递

​ 调用@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起@Builder方法内的UI刷新。所以当使用状态变量的时候,推荐使用按引用传递。

@Builder
function commonBuilder(wid: number) {
  Column() {
    Image($r('app.media.startIcon'))
      .width(wid)
  }
}
@Entry
@Component
struct Index {
  @State wid: number = 50
  build() {
    Column() {
      commonBuilder(this.wid)
      Button("刷新UI")
        .onClick(() => {
          this.wid = 100
        })
    }.width("100%")
  }
}

PixPin_2024-08-19_16-47-49.gif

按引用传递

​ 按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。

class CL {
  param1: number = 10
}
@Builder
function commonBuilder(params: CL) {
  Column() {
    Image($r('app.media.startIcon'))
      .width(params.param1)
  }
}
@Entry
@Component
struct Index {
  @State wid: number = 50

  build() {
    Column() {
      commonBuilder({ param1: this.wid })
      Button("刷新UI")
        .onClick(() => {
          this.wid = 100
        })
    }.width("100%")
  }
}

PixPin_2024-08-19_17-01-59.gif

2 状态管理装饰器

2.1 @State-管理组件拥有的状态-组件内状态

​ 用@State装饰的变量,称为状态变量。当状态变量发生改变时,UI会自动刷新。

说明:

​ a.被@State装饰的变量必须指定类型和初始化

​ b.@State装饰的变量生命周期与其所属自定义组件的生命周期相同

​ c.@State装饰的变量,是私有的,只能从组件内部访问

后续会继续更新装饰器相关的知识。