鸿蒙 自定义组件装饰器

此文章内容兼容API12,使用harmony next应用开发

@Builder

1,使用说明

  • 组件内部使用,此时是私有的组件构建函数装饰器
  • 全局使用

2,参数
(1)传参包括 值传递、引用传递两种方式
值传递。 此时哪怕传递状态变量,也不会引起UI刷新

引用传递 (对象字面量的形式),可以引起UI刷新

对象字面量:对象字面量是一个名值对列表,每个名值对之间用逗号分隔,并用一个大括号括起。各名值对表示对象的一个属性,名和值这两部分之间用一个冒号分隔,并且使用的时候不需要使用new关键字
var item={name: "tom", value:123}

@State buildTest:string = 'hey'
  @Builder
  BuildView() {
    Button('改变值')
      .onClick(() => this.buildTest = 'change')
    this.BuildParam1View(this.buildTest)//值传递
    this.BuildParam2View({param1:this.buildTest})//引用传递:对象字面量的形式
  }
  @Builder
  BuildParam1View(str:string) {
      Text(`值传递:${str}`) //不会刷新
  }
  @Builder
  BuildParam2View(clazz:BuildClazz) {
    Text(`引用传递:${clazz.param1}`)//会刷新
  }
}
class BuildClazz{
  param1 : string = 'BuildClazz'
}

(2)刷新说明

  • 仅在 引用传递时,且只有一个参数时,才会触发UI;
  • 引用传递,必须按照 对象字面量的形式,把所需属性一一传入,才会触发刷新
  • 若同时存在 值传递、引用传递两种方式,无法触发UI更新;若同时传递两个或以上,无法触发UI更新
  • 全局自定义 @Builder 组件,也可使用对象字面量形式的引用传递,触发刷新

3,嵌套
@Builder 内嵌套 @Builder 组件,或嵌套自定义组件,可以使用 $$ 范式

...{
...
    this.BuildParam3View({param1:this.buildTest})
  }

  @Builder
  BuildParam3View($$:BuildClazz) {
    Text(`嵌套使用:${$$.param1}`)//会刷新
    this.BuildParam3SonView($$)
  }
  @Builder
  BuildParam3SonView($$:BuildClazz) {
    Text(`嵌套使用(Son):${$$.param1}`)//会刷新
  }

4,@Builder 函数 最好要被Column/Row(根节点)包裹,否则直接使用if函数时,无法创建出组件

@Builder
  BuildParam3SonView() {
      if(...){  Text(`test1`) }
     else{  Text(`test2`) }
  }

@LocalBuilder

引入 @LocalBuilder,解决自定义组件间的父子关系,确保状态管理时保持一致
1,区别

@Build @LocalBuilder
可以再组件内声明,也可以全局声明 只能在组件内生命。

2,引用传递和值传递,效果场景都和 @Build 相同

@BuilderParam

用于扩展自定义组件。在使用自定义组件时,通过对 @BuilderParam 装饰的函数进行传参赋值等,为组件增加特定功能
类似于 slot 占位符

//自定义组件
...
  @Builder
  BuildParamView(){
    //两种方式都可,但存在区别,见下文
    BuildParamSonView({addHeader:() =>{this.BuildParamSonHeaderView()}})
    BuildParamSonView({addHeader:this.BuildParamSonHeaderView})
  }

  @Builder BuildParamSonHeaderView(){
    Text('我是 Header')
  }
}

@Component
export struct BuildParamSonView{
  @BuilderParam addHeader:()=>void
  build() {
    Column(){
      this.addHeader()
    }
  }
}

1,使用说明

  • 可将用@Builder修饰的自定义view,传递自定义组件中。使用 this. 方式引用
  • 必须声明类型
  • 可以结合@Require 使用,强制父组件传参
  • 本地初始化,及引用处,只能传递 @Builder 构建的函数

2,两种传递方式的区别

...
  @State label:string = '我是父'
  @Builder
  Parent(){
    //此种方式,this 指代的是子组件Son,因此展示为 ‘我是子 | 创建Header ’ 
    Son({addHeader:() =>{this.BuildView()}})
    // 此种方式,this 指代的是宿主组件Parent,因此展示为 ‘我是父 | 创建Header '
    Son({addHeader:this.BuildView})
  }

  @Builder BuildView(){
    Text(this.label+" | 创建Header")
  }
}

@Component
export struct Son{
  @State label:string = '我是子'
  @BuilderParam addHeader:()=>void
  build() {
    Column(){
      this.addHeader()
    }
  }
}

3,与此同时,如果想宿主组件 Parent 的状态改变,同步到自定义组件Son中,需要使用 第一种方式,让this 指代宿主组件Parent

Son({addHeader:() =>{this.BuildView()}})

4,@BuilderParam 支持参数,但需和 @Builder 一致

 @BuilderParam addHeader:( tmp : ClassA )=>void

@Style

@Builder 复用组件,@Style 复用样式

  • @Style 仅支持通用属性,和 通用事件
  • @Style 不支持参数
  • @Style 可以定义在组件内或全局,但不能跨文件,更不能跨模块 ; 不能使用 export 关键字
  • 组件内的 @Style 可访问组件的常量和状态变量

@Extend

用于扩展 原生组件 的样式

  • @Extend 支持 私有属性
  • @Extend 支持参数
  • 仅支持全局定义,不能在组件内使用
  • @Extend 参数支持 function,也可为状态变量
@Extend(Text) function makeMeClick(onClick: () => void) {
  .backgroundColor(Color.Blue)
  .onClick(onClick)
}

...
      Text(`${this.label}`)
        .makeMeClick(() => {this.onClickHandler()})
 ...

stateStyles

支持在不同状态下 ,样式变化。可和 @Style 联合使用

  • focused:获焦态。
  • normal:正常态。
  • pressed:按压态。
  • disabled:不可用态。
  • selected10+:选中态。

1,仅支持通用属性
2,可使用组件内的变量

 Button('Button1')
        .stateStyles({
          focused: {
            .backgroundColor('#ffffeef0')
          },
          pressed: {
            .backgroundColor('#ff707070')
          },
          normal: {
            .backgroundColor('#ff2787d9')
          }
        })

//----------------- SPLIT LINE -----------------------
 @Styles normalStyle() {
    .backgroundColor(Color.Gray)
  }

  @Styles pressedStyle() {
    .backgroundColor(Color.Red)
  }
...
Button('Button1')
        .stateStyles({
          normal: this.normalStyle,
          pressed: this.pressedStyle,
        })
...

@AnimatableExtend

自定义可动画的属性方法

@Require

@Require 作用于父子之间, 用于校验自定义组件中, @Prop、@State、@Provide、@BuilderParam 修饰的变量,和普通变量,是否必须传参

 @Require @State label: string = "Hello";
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。