鸿蒙Next封装组件全局通用属性

之前的文章中介绍过StylesExtend对基础组件的属性封装,可以节省相同组件设置相同属性的代码量,也方便统一修改管理。然而也有自己的局限性,如果在不同的文件中则不能引用。
细心的同学可能会发现,手势系列文章旋转手势、快滑手势、组合手势文章中都使用了Radio组件测试,使用了Extend封装基础属性。并且名字都不同,这是为什么呢?
例如我在多个文件中定义了相同的Radio属性方法:

@Extend(Radio)
function myRadioStyle() {
  .checked(false)
  .radioStyle({
    checkedBackgroundColor: Color.Green,  //开启状态底板颜色
    uncheckedBorderColor:Color.Red, //关闭状态描边颜色
    indicatorColor:Color.Yellow  //开启状态内部圆饼颜色
  })
  .height(20)
  .width(20)
}

由于@Extend不支持export,所以编译时,会出现以下错误:

ERROR: ArkTS:ERROR File: 
D:/.../SwipeGestureTest.ets:2:10
Duplicate function implementation.

如果使用相同的方法名,会提示方法重复实现
当我们在多个地方需要使用相同样式的组件时,我们不能每个页面都重新定义一遍,这样不仅代码冗余,如果需要修改,也是很大的工作量。因此,需要将使用频繁或者公用的属性抽离封装出来,统一修改使用。

解决以上问题,需要使用属性修改器(AttributeModifier)

首先看一下@Styles、@Extend和AttributeModifier的主要区别

能力 @Styles @Extend AttributeModifier
跨文件导出 不支持 不支持 支持
通用属性设置 支持 支持 支持
参数传递 不支持 支持 支持
多态样式 支持 不支持 支持
业务逻辑 不支持 不支持 支持

实现全局的通用属性设置,主要依靠AttributeModifier支持跨文件导出能力。@Styles和@Extend均是编译期处理,不支持跨文件的导出复用。
AttributeModifier是一个接口,T必须指定为组件对应的Attribute类型,或者是CommonAttribute。

declare interface AttributeModifier<T> {
   //组件普通状态时的样式
  applyNormalAttribute?(instance: T): void;
    //组件按压状态的样式
  applyPressedAttribute?(instance: T): void;
    //组件获焦状态的样式
  applyFocusedAttribute?(instance: T): void;
    //组件禁用状态的样式
  applyDisabledAttribute?(instance: T): void;
    //组件选中状态的样式
  applySelectedAttribute?(instance: T): void;

}

接下来以实现全局Radio属性为例介绍:
1.新建一个class 实现 AttributeModifier,传入泛型RadioAttribute
2.实现applyNormalAttribute方法,只需设置默认状态的样式即可
3.自定义参数,设置默认是否选中
4.将Extend的属性设置复制到applyNormalAttribute中实现。

export class MyRadioModifier implements AttributeModifier<RadioAttribute> {
  private isChecked:boolean = false
  constructor(checkd:boolean = false) {
    this.isChecked = checkd
  }
  //组件普通状态时的样式
  applyNormalAttribute(instance: RadioAttribute): void {
    instance
      .checked(this.isChecked)
      .radioStyle({
        checkedBackgroundColor: Color.Green,  //开启状态底板颜色
        uncheckedBorderColor:Color.Red, //关闭状态描边颜色
        indicatorColor:Color.Yellow  //开启状态内部圆饼颜色
      })
      .height(20)
      .width(20)
  }
}

使用方法:

@Local myRadioStyle:MyRadioModifier = new MyRadioModifier()
Radio({ value: 'r1', group: 'radioGroup' })
          .attributeModifier(new MyRadioModifier(true))
          .onChange((isChecked: boolean) => {
          })
Radio({ value: 'r2', group: 'radioGroup' })
          .attributeModifier(this.myRadioStyle)
          .onChange((isChecked: boolean) => {
          })

以上就可以在任何文件中使用Radio的设置属性了。

注意:
1.一个组件上同时使用属性方法和applyNormalAttribute设置相同的属性,遵循属性覆盖原则,即后设置的属性生效。
2.一个Modifier实例对象可以在多个组件上使用。
3.一个组件上多次使用applyNormalAttribute设置不同的Modifier实例,同样遵循属性覆盖原则。

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

推荐阅读更多精彩内容