管理组件拥有的状态

  1. 1.

    @Local装饰器(组件内部状态)

    • @Local表示组件内部的状态,被@Local装饰的变量无法从外部初始化,必须在组件内部初始化。

    • 当装饰变量为对象时,仅能观察到对类对象整体赋值的变化,无法直接观察到对类属性赋值的变化,对类成员属性的观察依赖@ObservedV2和@Trace装饰器。

    • 当修饰简单类型数组时,可以观察到数组整体或数组项的变化。

    • 当装饰的变量是嵌套类或对象数组时,@Local无法观察深层对象属性的变化。

    • 当装饰的类型是Date、Map、Set时,参照@State。

  2. 2.

    @Param(组件外部输入)

    • @Param不仅可以接受组件外部输入,还可接受@Local的同步变化。父到子单向同步。

    • @Param装饰的变量支持本地初始化,但不允许在组件内部直接修改。

    • 被@Param装饰的变量能够在初始化自定义组件时从外部传入,当数据源也是状态变量时,数据源的修改会同步给@Param。

    • @Param可以接受任意类型的数据源,包括普通变量、状态变量、常亮、函数返回值等。

    • @Param装饰的变量变化时,会刷新该变量关联的组件。

    • 当装饰的变量类型是类对象时,仅可以观察到对类对象整体赋值的变化,无法直接观察到对类成员属性赋值的变化。对类成员属性的观察依赖@ObservedV2和@Trace装饰器。

    • 当装饰的变量为数组、Date、Map、Set时,参照@Local。

    • @Param装饰器只能在@ComponentV2装饰器的自定义组件中使用。

    • @Param装饰的变量表示组件外部输入,需要初始化。支持使用本地初始值或外部传入值进行初始化。当存在外部传入值时,优先使用外部传入值。不允许既不使用本地初始值,也不使用外部传入值。

    • 使用@Param装饰的变量在子组件无法被直接修改。但是,如果装饰的变量是对象类型,在子组件中可以修改对象的属性。

  3. 3.

    @Once(初始化同步一次)

    • @Once装饰器在变量初始化时接受外部传入值进行初始化,后续数据源更改不会同步给子组件。

    • @Once不影响@Param的观测能力,仅针对数据源的变化做拦截。

    • @Once与@Param搭配使用时,可以接触@Param无法在本地修改的限制,并能够触发UI刷新。此时@Param和@Once效果类似于@Local,但@Param和@Once还能接收外部传入的初始值。

    • @Once仅在@ComponentV2装饰的自定义组件中与@Param搭配使用。

  4. 4.

    @Event装饰器(规范组件输出)

    • @Event主要配合@Param实现数据的双向同步。由于@Param装饰的变量在本地无法更改,使用@Event装饰器装饰回调方法并调用,可以实现更新数据源的变量,再通过@Local的同步机制,将修改同步回@Param装饰的变量,以此达到主动更新@Param装饰变量的效果。

    • @Param标志着组件的输入,表明该变量受父组件影响,而@Event标志着组件的输出,可以通过该刚方法影响父组件。使用@Event装饰回调方法是一种规范,表明该回调作为自定义组件的输出。父组件需要判断是否提供对应方法用于子组件更改@Param变量的数据源。

    • @Event只能用在@ComponentV2装饰的自定义组件中。当装饰非方法类型的变量时,不会有任何作用。

  5. 5.

    @Provider装饰器和@Consumer装饰器(跨组件层级双向同步)

    • @Provider,即数据提供方,其所有的子组件都可以通过@Consumer绑定相同的key来获取@Provider提供的数据。

    • @Consumer,即数据消费方,可以通过绑定同样的key获取其最近父节点的@Provider的数据,当查找不到@Provider的数据时,使用本地默认值。

    • @Provider和@Consumer装饰的数据类型需要一致。

    • 当需要在父组件中向子组件注册回调函数时,可以使用@Provider和@Consumer装饰回调方法来实现。

    • @Provider和@Consumer只能观察到数据本身的变化。如果需要观察其装饰的复杂数据类型的属性变化,必须配合@Trace一起使用。

    • @Provider可以在组件树上重名,@Consumer会向上查找其最近父节点的@Provider的数据。

    • @Provider和@Consumer装饰的变量可以初始化子组件中的@Param装饰的变量。

管理数据对象的状态

  1. 1.

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

    • ObservedV2和@Trace必须配合使用。使用@ObservedV2与@Trace装饰器的类,需通过new操作实例化后,才具备被观测变化的能力。

    • 嵌套类中使用@Trace装饰的属性具有被观测变化的能力。

    • 继承类中使用@Trace装饰的属性具有被观测变化的能力。

    • 类中使用@Trace装饰的静态属性具有被观测变化的能力。

    • 非@Trace装饰的成员属性用在UI上无法触发UI刷新。

    • @ObservedV2仅能装饰class,无法装饰自定义组件和struct中。

    • @Trace不能用在没有被@ObservedV2装饰的class上。

    • @ObservedV2、@Trace不能与@Observed、@Track混合使用。

    • @ObservedV2和@Trace不能和V1装饰器混合使用,编译报错。

    • 继承自@ObservedV2的类无法和@State等V1的装饰器混用,运行时报错。

    • @ObservedV2装饰对象的序列化和反序列化会使用类失去观察能力,需要配合三方库class-transformer。

    • router传递的@ObservedV2类型显示异常,需要配合class-transformer。

  2. 2.

    @Monitor装饰器(状态变量修改监听)

    • @Monitor装饰器支持在@ComponetV2装饰的自定义组件中使用,未被状态变量装饰器@Local、@Param、@Provider、@Consumer、@Computed装饰的变量无法被@Monitor监听到变化。

    • @Monitor装饰器支持在类中与@ObservedV2、@Trace配合使用,不允许在未被@ObservedV2装饰的类中使用@Monitor装饰器。未被@Trace装饰的属性无法被@Monitor监听到变化。

    • 当观测到属性变化时,@Monitor装饰器定义的回调方法将被调用。判断属性是否相等使用的是严格的===。当一次事件中多次改变同一属性时,将会使用初始值和最终值进行比较判断是否变化。

    • 单个@Monitor装饰器能够同时监听多个属性的变化,当这些属性在一次事件中共同变化时,只会触发一次@Monitor的回调方法。

    • @Monitor装饰器具有深度监听能力,能够监听嵌套类、多维数组、对象数组中指定项的变化。但是要求被@ObservedV2与@Trace装饰。

    • 在继承场景中,可以在父子组件中对同一个属性分别定义@Monitor进行监听,当属性变化时,父子中定义的@Monitor回调均会被调用。

    • @Watch无法深度监测,@Monitor同时监听多个状态变量,这些变量名用‘,’隔开。

    • 当状态变量变为undefined或者undefined变为对象时,不会触发回调。

  3. 3.

    @Computed装饰器(计算属性)

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

    • @Computed可初始化子组件@Param,@ComponentV2中@Computed会在自定义组件创建的时候初始化,触发@Computed计算。@ObservedV2装饰的类的@Computed会在@ObservedV2装饰的类实例创建后,异步初始化,触发@Computed计算。

    • @Computed装饰的方法只有在初始化,或者其被计算的状态变量改变时,才会发生重新计算。

    • @Computed装饰的属性是只读的,不允许赋值。

    • @Computed为方法装饰器,仅能装饰getter方法。

    • @Computed装饰的getter方法中,不能改变参与计算的属性,以防止重复执行计算属性导致appfreeze。

  4. 4.

    @Type装饰器(标记类属性的类型)

    • 为了实现序列化类时不丢失属性的复杂类型,开发者可以使用@Type装饰器装饰类属性。

    • @Type的目的是标记类属性,配合PersistenceV2使用,防止序列化时类丢失。

    • 只能用在@ObserbedV2装饰的类中,不能用在自定义组件中。

管理应用拥有的状态

  1. 1.

    AppStorageV2(应用全局UI状态存储)

    • AppStorageV2是在应用UI启动时会被创建的单例。它用于提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorageV2将在应用运行过程保留其数据。数据通过唯一的键字符串值访问。需要注意的是,AppStorage与AppStorageV2之间数据互不共享。

    • AppStorageV2可以修改connnect的返回值,实现与UI组件的同步。

    • AppStorageV2支持应用的主线程内多个UIAbility实例间状态共享。

    • connect:创建或获取存储的数据。

    • remove:删除指定key的存储数据。

    • keys:返回所有AppStorageV2的key。

    • 只支持class类型。不支持存储基本类型。

  2. 2.

    PersistenceV2(持久化存储UI状态)

    • PersistenceV2是在应用UI启动时会被创建的单例。它的目的是提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。数据通过唯一的键值字符串访问。不同于AppStorageV2,PersistenceV2还将最新数据存储在设备磁盘上持久化。

    • 对于PersistenceV2关系的@ObservedV2对象,该对象@Trace属性的变化,会触发整个关联对象的自动持久化;非@Trace属性的变化则不会,如有必要,可调用PersistenceV2 API手动持久化。注意:被PersistenceV2持久化的类属性必须有初始值,否则不支持持久化。

    • PersistenceV2可以和组件同步,且可以在应用业务逻辑中被访问。

    • PersistenceV2支持应用的主线程内多个UIAbility实例间的状态共享。

    • connect、globalConnect:创建或获取存储的数据。

    • remove:删除指定key的存储数据。删除PersistenceV2中不存在的key会报警告。

    • keys:返回所有PersistenceV2中的key。包括module级别存储路径和应用级别存储路径中的所有key。

    • save:手动持久化数据。

    • notifyOnError:响应序列化或反序列化失败的回调。

    • 单个key支持数据大小约8k,过大会导致持久化失败。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐