管理数据的状态

@ObservedV2装饰器和@Trace装饰器:类属性变化观测

ObservedV2和Trace需要一起使用,作用是监听类属性的变化

在下面的例子中如果没有加入上述两个装饰器,则不会监听属性的变化

ts 复制代码
@ObservedV2
class UserInfo {
  @Trace name: string = ""
}

@Entry
@ComponentV2
struct Index {
  userinfo: UserInfo = new UserInfo()
  build() {
    Column() {
      Text(this.userinfo.name)
      Button("click")
        .onClick(()=>{
          this.userinfo.name = 'lele'
        })
    }
    .height('100%')
    .width('100%')
  }
}

上述装饰器的强大不止于此,在嵌套类中一样可以检测

ts 复制代码
@ObservedV2
class UserInfo {
  @Trace name: string = ""
}

class User extends UserInfo{}
@Entry
@ComponentV2
struct Index {
  user: User = new User()
  build() {
    Column() {
      Text(this.user.name)
      Button("click")
        .onClick(()=>{
          this.user.name = 'lele'
        })
    }
    .height('100%')
    .width('100%')
  }
}
@Monitor装饰器:状态变量修改异步监听

@Monitor监听的变量需要被@Local、@Param、@Provider、@Consumer、@Computed装饰,未被状态变量装饰器装饰的变量在变化时无法被监听。@Monitor可以同时监听多个状态变量,这些变量名之间用","隔开。

ts 复制代码
@Entry
@ComponentV2
struct Index {
  @Local name:string = ''
  @Monitor('name')
  nameChange(monitor:IMonitor){
    // 获取值
    this.getUIContext().getPromptAction().showToast({
      message:`path: ${monitor.value()?.path} change from ${monitor.value()?.before} to ${monitor.value()?.now}`
    })
    // output: path: name change from to lele`
    // monitor.dirty 变化路径的数组。
    this.getUIContext().getPromptAction().showToast({
      message:`dirty: ${monitor.dirty}`
    })
    // output:dirty:name
  }
  build() {
    Column() {
      Text(this.name)
      Button("click")
        .onClick(()=>{
          this.name = 'lele'
        })
    }
    .height('100%')
    .width('100%')
  }
}

当name改变时,会触发nameChange方法

@SyncMonitor装饰器:状态变量修改同步监听

api23才有

@SyncMonitor装饰器用于同步监听状态变量修改,使得状态变量具有深度监听的能力:

SyncMonitor可以监听深层属性的变化,并能够根据更改前后的值做分类处理。

ts 复制代码
@ObservedV2
class Info {
  @Trace public value: number = 50;
}

@ObservedV2
class UIStyle {
  public info: Info = new Info();
  @Trace public color: Color = Color.Black;
  @Trace public fontSize: number = 45;

  @SyncMonitor('info.value')
  onValueChange(monitor: IMonitor) {
    let lastValue: number = monitor.value()?.before as number;
    let curValue: number = monitor.value()?.now as number;
    if (lastValue != 0) {
      let diffPercent: number = (curValue - lastValue) / lastValue;
      if (diffPercent > 0.1) {
        this.color = Color.Red;
        this.fontSize = 50;
      } else if (diffPercent < -0.1) {
        this.color = Color.Green;
        this.fontSize = 40;
      } else {
        this.color = Color.Black;
        this.fontSize = 45;
      }
    }
  }
}

@Entry
@ComponentV2
struct Index {
  textStyle: UIStyle = new UIStyle();

  build() {
    Column() {
      Text(`Important Value: ${this.textStyle.info.value}`)
        .fontColor(this.textStyle.color)
        .fontSize(this.textStyle.fontSize)
      Button('change!')
        .onClick(() => {
          this.textStyle.info.value = Math.floor(Math.random() * 100) + 1;
        })
    }
  }
}
@Computed装饰器:计算属性

当开发者使用相同的计算逻辑重复绑定在UI上时,为了防止重复计算,可以使用@Computed计算属性。计算属性中依赖的状态变量变化时,只会计算一次。这解决了UI多次重用该属性导致的重复计算和性能问题。

ts 复制代码
@Entry
@ComponentV2
struct Index {
  @Local firstname:string = 'shui'
  @Local lastname:string = 'shenhuole'
  fullNameFunc():string{
    console.log('fullNameFun');
    return this.firstname + this.lastname
  }
  @Computed
  get fullName(){
    console.log('fullName');
    return this.fullNameFunc()
  }
  build() {
    Column(){
      Text(`${this.fullNameFunc()}`)
      Text(`${this.fullNameFunc()}`)
      Text(`${this.fullNameFunc()}`)
      Text(`${this.fullNameFunc()}`)
      Text(`${this.fullName}`)
      Text(`${this.fullName}`)
      Text(`${this.fullName}`)
      Text(`${this.fullName}`)
    }
  }
}

输出结果 在使用@computed装饰器的属性时,会自动缓存计算结果,下次使用时,会直接返回缓存结果,而不会重复计算。

bash 复制代码
03-23 23:18:38.016   7683-7683     A03d00/JSAPP                    com.examp...lication  I     fullName
03-23 23:18:38.016   7683-7683     A03d00/JSAPP                    com.examp...lication  I     fullNameFun
03-23 23:18:38.021   7683-7683     A03d00/JSAPP                    com.examp...lication  I     fullNameFun
03-23 23:18:38.022   7683-7683     A03d00/JSAPP                    com.examp...lication  I     fullNameFun
03-23 23:18:38.023   7683-7683     A03d00/JSAPP                    com.examp...lication  I     fullNameFun
03-23 23:18:38.023   7683-7683     A03d00/JSAPP                    com.examp...lication  I     fullNameFun
相关推荐
Keya22 分钟前
HarmonyOS 开发实战:用 util.Aspect 玩转 AOP 切面编程
harmonyos
威哥爱编程1 小时前
HarmonyOS 7 Agent 开发实战 03:Tool Calling 让 AI 查实时订单与库存
agent·harmonyos
威哥爱编程1 小时前
HarmonyOS 7 Agent 开发实战 02:Agent 工程脚手架与对话 UI 骨架
agent·harmonyos
Georgewu9 小时前
【HarmonyOS 7】 HarmonyOS 应用 Skill创建和编排详解
harmonyos
Georgewu11 小时前
【HarmonyOS 7】 应用 Agent 接入云 A2A 与端 A2A 的实践详解
harmonyos
马剑威(威哥爱编程)17 小时前
【共创稿事节】HarmonyOS 7 Agent 开发实战 05:流式输出做打字机对话
华为·harmonyos
OH_TPC20 小时前
【鸿蒙优选三方库】@ohos/coap:让鸿蒙设备说上 IoT 的母语
物联网·华为·harmonyos·鸿蒙
程序猿追21 小时前
渐变中间那一格怎么算?用 colormath 做个鸿蒙调色器
华为·harmonyos
程序猿追1 天前
在 HarmonyOS 6 上做了张 3D 翻转卡片,正面背面来回翻
3d·华为·harmonyos
小π军1 天前
安卓、iOS、鸿蒙三端的理解
android·ios·harmonyos