管理数据的状态

@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
相关推荐
特立独行的猫a11 分钟前
仓颉语言原生 Coding Agent:cjh · 仓颉语言实现的 Harness
ai·agent·harmonyos·仓颉·cangjie·harness
大锅盖117 分钟前
警示橙如何驱动巡检闭环?ArkUI 物业安全平台的声明式实现
安全·华为·harmonyos
贾伟康30 分钟前
【时光清单|03】HarmonyOS ArkTS 提醒服务实战:计算触发时间并防止重复注册
harmonyos·arkts·后台任务·幂等设计·通知提醒
李蚊子30 分钟前
从代理提醒到真实响铃:懒熊闹钟的鸿蒙开发实践
前端·harmonyos
GKxx34 分钟前
在 HarmonyOS 上从源码构建 GCC 16(gcc/g++ + libstdc++ + libsanitizer):完整记录
c++·华为·harmonyos·鸿蒙·gcc
贾伟康36 分钟前
【时光清单|04】HarmonyOS ArkTS 通知服务实战:管理权限、渠道和点击跳转
harmonyos·arkts·系统通知·notificationkit·wantagent
黑臂麒麟1 小时前
HarmonyOS随手账本App——从项目搭建到数据模型设计
华为·app·鸿蒙
黑臂麒麟1 小时前
Harmony鸿蒙实战应用4:随手账本——编辑与删除账单
ubuntu·华为·鸿蒙
独守一片天1 小时前
HarmonyOS|鸿蒙新生态服务卡片设计与状态同步
华为·harmonyos
黑臂麒麟1 小时前
HarmonyOS 7 碰一碰实战:手机轻触电脑,精准插入图片到指定位置
华为·智能手机·arkts·鸿蒙