首页 > 其他分享 >OpenHarmony 状态变量更改通知:@Watch 装饰器

OpenHarmony 状态变量更改通知:@Watch 装饰器

时间:2023-10-31 20:03:51浏览次数:35  
标签:OpenHarmony shopBasket Watch number 组件 状态变量 total

@Watch 应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用 @Watch 为状态变量设置回调函数。

说明:

从 API version 9 开始,该装饰器支持在 ArkTS 卡片中使用。

概述

@Watch 用于监听状态变量的变化,当状态变量变化时,@Watch 的回调方法将被调用。@Watch 在 ArkUI 框架内部判断数值有无更新使用的是严格相等(===),遵循严格相等规范。当在严格相等为 false 的情况下,就会触发 @Watch 的回调。

装饰器说明

 

语法说明

观察变化和行为表现

当观察到状态变量的变化(包括双向绑定的 AppStorage 和 LocalStorage 中对应的 key 发生的变化)的时候,对应的 @Watch 的回调方法将被触发;

@Watch 方法在自定义组件的属性变更之后同步执行;

如果在 @Watch 的方法里改变了其他的状态变量,也会引起状态变更和 @Watch 的执行;

在第一次初始化的时候,@Watch 装饰的方法不会被调用,即认为初始化不是状态变量的改变。只有在后续状态改变时,才会调用 @Watch 回调方法。

限制条件

建议开发者避免无限循环。循环可能是因为在 @Watch 的回调方法里直接或者间接地修改了同一个状态变量引起的。为了避免循环的产生,建议不要在 @Watch 的回调方法里修改当前装饰的状态变量;

开发者应关注性能,属性值更新函数会延迟组件的重新渲染(具体请见上面的行为表现),因此,回调函数应仅执行快速运算;

不建议在 @Watch 函数中调用 async await,因为 @Watch 设计的用途是为了快速的计算,异步行为可能会导致重新渲染速度的性能问题。

使用场景

@Watch 和自定义组件更新

以下示例展示组件更新和 @Watch 的处理步骤。count 在 CountModifier 中由 @State 装饰,在 TotalView 中由 @Prop 装饰。

@Component
struct TotalView {
  @Prop @Watch('onCountUpdated') count: number = 0;
  @State total: number = 0;
  // @Watch cb
  onCountUpdated(propName: string): void {
    this.total += this.count;
  }
 
  build() {
    Text(`Total: ${this.total}`)
  }
}
 
@Entry
@Component
struct CountModifier {
  @State count: number = 0;
 
  build() {
    Column() {
      Button('add to basket')
        .onClick(() => {
          this.count++
        })
      TotalView({ count: this.count })
    }
  }
}

  

处理步骤:

CountModifier 自定义组件的 Button.onClick 点击事件自增 count。

由于 @State count 变量更改,子组件 TotalView 中的 @Prop 被更新,其 @Watch('onCountUpdated')方法被调用,更新了子组件 TotalView 中的 total 变量。

子组件 TotalView 中的 Text 重新渲染。

@Watch 与 @Link 组合使用

以下示例说明了如何在子组件中观察 @Link 变量。

 
class PurchaseItem {
  static NextId: number = 0;
  public id: number;
  public price: number;
 
  constructor(price: number) {
    this.id = PurchaseItem.NextId++;
    this.price = price;
  }
}
 
@Component
struct BasketViewer {
  @Link @Watch('onBasketUpdated') shopBasket: PurchaseItem[];
  @State totalPurchase: number = 0;
 
  updateTotal(): number {
    let total = this.shopBasket.reduce((sum, i) => sum + i.price, 0);
    // 超过100欧元可享受折扣
    if (total >= 100) {
      total = 0.9 * total;
    }
    return total;
  }
  // @Watch 回调
  onBasketUpdated(propName: string): void {
    this.totalPurchase = this.updateTotal();
  }
 
  build() {
    Column() {
      ForEach(this.shopBasket,
        (item:PurchaseItem) => {
          Text(`Price: ${item.price.toFixed(2)} €`)
        },
        (item:PurchaseItem) => item.id.toString()
      )
      Text(`Total: ${this.totalPurchase.toFixed(2)} €`)
    }
  }
}
 
@Entry
@Component
struct BasketModifier {
  @State shopBasket: PurchaseItem[] = [];
 
  build() {
    Column() {
      Button('Add to basket')
        .onClick(() => {
          this.shopBasket.push(new PurchaseItem(Math.round(100 * Math.random())))
        })
      BasketViewer({ shopBasket: $shopBasket })
    }
  }
}

  

处理步骤如下:

BasketModifier 组件的 Button.onClick 向 BasketModifier shopBasket 中添加条目;

@Link 装饰的 BasketViewer shopBasket 值发生变化;

状态管理框架调用 @Watch 函数 BasketViewer onBasketUpdated 更新 BasketViewer TotalPurchase 的值;

@Link shopBasket 的改变,新增了数组项,ForEach 组件会执行 item Builder,渲染构建新的 Item 项;@State totalPurchase 改变,对应的 Text 组件也重新渲染;重新渲染是异步发生的。

标签:OpenHarmony,shopBasket,Watch,number,组件,状态变量,total
From: https://www.cnblogs.com/openharmony/p/17801149.html

相关文章

  • watch之在特殊时间之后才开始监听某变量
    前提:watch监听属性所执行的函数会在一开始就执行,immediate:true时会执行两次,就算是immediate:false也是执行一次,而我想要初始时不执行,就需要使用$watch这个方法了三个参数:监听对象回调函数配置属性:deep,immediate等(对象形式)监听顶层的属性,比如this.xxx//fun为属性变化时......
  • Before You Install Flask...Watch This! Flask Fridays #1
    flask官网:https://flask.github.net.cn/ git官网:https://git-scm.com/ 建立文件: 建立虚拟环境、激活: sourcevirt/Scripts/activate建立文件: touchhello.py以项目方式打开: fromflaskimportFlask,render_template#创建一个flask实例app=Flask(_......
  • watchfiles + importlib == automatical rerun
    uvicornhttps://www.uvicorn.org/settings/此ASGI为开发者模式提供了,代码更改,自动加载功能。此功能如何实现?依赖两个库:watchfilesimportlibDevelopment¶--reload-Enableauto-reload.Uvicornsupportstwoversionsofauto-reloadingbehaviorenabledbythisopt......
  • Vue:watch的多种使用方法
    好家伙, 补了一下watch的多种用法 1.属性:方法(最常用)使用最广泛的方式是将watch选项设置为一个对象,对象的属性是要观测的数据属性,值是一个回调函数,该回调函数会在属性变化时触发。例如:watch:{firstName:function(newVal,oldVal){console.log('firstNamec......
  • vue3 watch 用法
    <scriptsetup>import{ref,computed,watch}from'vue'constnum=ref(1)constname=ref('ming')constobj=ref({name:'小明',age:30})//watch简单类型//watch(num,(newValue,oldVal......
  • [Vue]computed和watch的区别
    computed和watch之间的区别: 1.computed能完成的功能,watch都可以完成。 2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。两个重要的小原则: 1.所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。 2.所有不......
  • 重磅官宣 | 第二届OpenHarmony技术峰会,邀您共启智联未来
    "下一个技术未来在哪里?"11月4日  技术大咖齐聚北京为你解答一场主论坛+八大开源领域分论坛探究终端操作系统十大技术挑战方向与全球开源操作系统技术领袖、实践专家、一线导师携手共绘OpenHarmony开源生态璀璨星图!......
  • 重磅官宣 | 第二届OpenHarmony技术峰会,邀您共启智联未来
     "下一个技术未来在哪里?"11月4日  技术大咖齐聚北京为你解答 一场主论坛+八大开源领域分论坛探究终端操作系统十大技术挑战方向 与全球开源操作系统技术领袖、实践专家、一线导师携手共绘OpenHarmony开源生态璀璨星图!  点击链接,预约直播......
  • OpenHarmony Meetup成都站招募令
    OpenHarmony Meetup城市巡回成都站火热招募中!!日期:2023年10月27日14:00地点:电子科技大学(沙河校区)学术交流中心一楼104会议室与OpenHarmony技术大咖近距离互动,分享技术见解,结交志同道合的朋友!活动主题聚焦OpenHarmony开源创新~议题内容设置由浅入深,带您一步步深入了解OpenHarmony技......
  • Unity中国、Cocos为OpenHarmony游戏生态插上腾飞的翅膀
    Unity中国、Cocos为OpenHarmony游戏生态插上腾飞的翅膀2023年是OpenHarmony游戏生态百花齐放的一年!为了扩展OpenHarmony游戏生态,OpenHarmony在基金会成立了游戏SIG小组,游戏SIG小组联合cocos,从cocos2dx入手一周内快速适配了cocos2.2.6的MVP版本,随后又分别适配了cocos2dx 3.x、4.x版......