HarmonyOS(46) 为控件设置动态属性或自定义属性:AttributeModifier

1、AttributeModifier的优点

声明式语法引入了@Styles@Extend两个装饰器,可以解决部分复用的问题,但是存在以下受限场景:

  • @Styles和@Extend均是编译期处理,不支持跨文件的导出复用。
  • @Styles仅能支持通用属性、事件,不支持组件特有的属性。
  • @Styles虽然支持在多态样式下使用,但不支持传参,无法对外开放一些属性。
  • @Extend虽然能支持特定组件的私有属性、事件,但同样不支持跨文件导出复用。
  • @Styles、@Extend对于属性设置,无法支持业务逻辑编写,动态决定是否设置某些属性。只能通过三元表达式对所有可能设置的属性进行全量设置,设置大量属性时效率低下。

AttributeModifier可以让开发者动态设置组件的属性,支持开发者在属性设置时使用if/else语法,且根据需要使用多态样式设置属性。
与@Styles和@Extend相比,AttributeModifier的能力和灵活性更好。当前持续在构建全量的属性、事件设置能力,推荐使用。

2、AttributeModifier的使用案例

2.1 动态改变按钮的颜色

点击按钮,切换按钮的背景颜色。
在这里插入图片描述

//自定义动态属性
class MyButtonModifier implements AttributeModifier<ButtonAttribute> {
  isDark: boolean = false
  applyNormalAttribute(instance: ButtonAttribute): void {
    if (this.isDark) {
      instance.backgroundColor(Color.Black)
    } else {
      instance.backgroundColor(Color.Red)
    }
  }
}



struct attributeDemo {
   modifier: MyButtonModifier = new MyButtonModifier()

  build() {
    Row() {
      Column() {
        Button("Button")
          //设置动态属性
          .attributeModifier(this.modifier)
          .onClick(() => {
            this.modifier.isDark = !this.modifier.isDark
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

2.2、分别设置普通状态和按下状态颜色

AttributeModifier提供了applyPressedAttribute组件方法,让我们在按下按钮时改变控件的样式,比如按下按钮时背景颜色是红色,松开时变黑色:
在这里插入图片描述

class MyButtonModifier implements AttributeModifier<ButtonAttribute> {
 //正常状态是黑色
  applyNormalAttribute(instance: ButtonAttribute): void {
    instance.backgroundColor(Color.Black)
  }
 //点击是变红色
  applyPressedAttribute(instance: ButtonAttribute): void {
    instance.backgroundColor(Color.Red)
  }
}



struct attributePressedDemo {
   modifier: MyButtonModifier = new MyButtonModifier()

  build() {
    Row() {
      Column() {
        Button("Button")
          .attributeModifier(this.modifier)
      }
      .width('100%')
    }
    .height('100%')
  }
}

AttributeModifier在开发过程中可以用来优化UI,详见UI组件性能优化

3、性能优化的利器

当需要给自定义组件设置较多属性时,推荐使用自定义AttributeModifier的方式来动态设置自定义组件的属性,减少节点数量的同时,也避免了参数过多导致耗时的问题,具体优化示例如下所示:

// 使用动态属性设置时,需要继承AttributeModifier,自行实现一个Modifier,然后设置到需要的组件上
class ColumnModifier implements AttributeModifier<ColumnAttribute> {
  width: number = 0;
  height: number = 0;
  backgroundColor: ResourceColor | undefined = undefined;

  applyNormalAttribute(instance: ColumnAttribute): void {
    instance.width(this.width);
    instance.height(this.height);
    instance.backgroundColor(this.backgroundColor);
  }
}



struct CustomComponentModifier {
  modifier: ColumnModifier = new ColumnModifier();

  aboutToAppear(): void {
    this.modifier.width = 100;
    this.modifier.height = 100;
    this.modifier.backgroundColor = Color.Red;
  }

  build() {
    Column() {
      ModifierCustom({ modifier: this.modifier })
    }
  }
}


struct ModifierCustom {
    modifier: AttributeModifier<ColumnAttribute>;

  build() {
    Column() {
      Text('Hello Word')
    }.attributeModifier(this.modifier)
  }
}

参考资料

动态属性设置
UI组件性能优化
组件嵌套优化
AttributeModifier官方文档

### HarmonyOS 中的状态管理教程和最佳实践 #### 组件内状态管理 在HarmonyOS的ArkUI框架中,组件内部可以通过声明属性的方式来进行简单的状态管理。对于较为复杂的场景,则推荐使用`@State`装饰器来定义可变状态变量[^1]。 ```typescript import { State, Component } from 'harmony'; @Component class MyComponent { @State() message: string = "Hello World"; } ``` #### 高级用法之依赖注入模式 针对跨多个层次结构传递数据的需求,可以采用`@Provide/@Consume`机制实现父子组件间的高效通信: - `@Provide`: 将父组件的数据暴露给子组件; - `@Consume`: 子组件通过此标签获取来自祖先节点提供的资源; 这种方式不仅简化了代码逻辑,同时也提高了性能表现。 #### 状态管理优化策略 为了避免潜在的问题并提高应用程序效率,在实际项目开发过程中应当遵循以下几点建议[^2]: - **减少循环体内对状态对象的操作**:频繁读取修改会增加渲染负担,应尽可能移至外部处理后再批量更新。 - **精简状态树规模**:只保留必要的全局共享部分作为顶层Store实例的一部分,其他局部变化可以直接由各业务模块自行维护而不必上升到整个App层面统一管控。 - **利用中间件缓存计算结果**:当某些派生值基于现有state重新求解耗时较长时,考虑引入额外的记忆化手段避免重复劳动。 #### 自定义属性修饰工具类设计思路 为了增强系统的灵活性以及便于后续迭代升级,创建了一个名为`BaseModifier<T>`的基础抽象基类继承自`AttributeModifier<T>`接口[^3]。此类允许使用者以链式语法动态调整视图控件的各项参数配置项而无需每次都手动编写冗长繁琐的方法签名列表。 ```typescript // 定义泛型约束条件下的通用操作模板 abstract class BaseModifier<T> implements AttributeModifier<T> { protected instance: T; constructor(targetInstance: T){ this.instance = targetInstance; } public abstract applyNormalAttribute(): void; } // 实际应用场景下具体化的实现版本 class TextColorModifier extends BaseModifier<Button>{ private colorValue:string; setColor(color:string):this{ this.colorValue=color; return this; } override applyNormalAttribute(){ (this.instance as Button).setTextColor(this.colorValue); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭梧悠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值