
【HarmonyOS Next】鸿蒙状态管理V2装饰器详解 原创
【HarmonyOS Next】鸿蒙状态管理V2装饰器详解
一、为什么需要V2状态管理装饰器?
首先我们需要了解什么是状态管理?在鸿蒙应用开发中,状态管理指的是,管理数据变化去刷新UI的整个过程。
举个例子,比如在界面中标题文本的动态刷新,从A刷新成B,这个文本的刷新过程,其实就是个状态的变化过程。整个过程的处理可以称之为状态管理。
鸿蒙使用的ArkUI框架进行渲染,配套的ArkTS是声明式编程,只需要关心数据的变化,数据变UI就相应的需要去更新。和传统的命令式编程相比,省去了寻找对应UI组件,去填充改变刷新,再让UI进行刷新的过程。
为了实现上述的UI动态渲染效果。鸿蒙提供了状态装饰器的概念工具,来实现数据到UI的便捷更新同步。
V1状态装饰器于此产生:围绕着@State这个数据监听开关,配套的装饰器来一起实现刷新行为,因为UI界面分为组件,界面。需要维护子母关系。所以就用到了@Prop 单数据流动,@Link 双数据流动,@Provide/@Consume 跨层级传递数据,@Observed和@ObjectLink 监听实现多层级嵌套对象的更新。
自从api7开始,一直到api10。V1的实际使用中,开发人员发现@Observed和@ObjectLink 监听实现多层级嵌套对象的更新的方案,太过于臃肿。
当需要监听处理更新的多层级对象是七八层,就需要配套创建七八层的ObjectLink,代码太过于冗余。
代码举例如下:
需要进行嵌套数据更新的层级,要抽离ItemView,在其中进行ObjectLink的处理。由此逻辑推断,如果我的数据对象有十层,每层都有数据需要更新的业务逻辑,(极限情况),代码冗余十分致命。
正因为以上的缺陷,V2状态管理装饰器由此诞生。但是目前开发进程还有堵塞点,官方建议慎重使用V2。
二、V2状态管理装饰器怎么用?
综上所述,我们知道解决多层嵌套对象刷新的痛点,是V2的主要任务。
其中@ObservedV2和@Trace,代替了@Observed和@ObjectLink。
相对于V1的监听原理,使用代理模式的监听数据变化。V2更加彻底且解耦,直接在数据本身进行观察监听。
代码举例如下:
首先要给需要刷新的多层对象定义类,添加@ObservedV2修饰。这个和V1区别不大。之后是使用@Trace直接修饰在需要监听的属性之前,代表该属性需要观察。此时我们就需要关心这个属性,在对象多少层了。
@ComponentV2装饰器:自定义组件
@Local 组件内部状态
@Local可理解为v1版本的@State,当被@Local装饰的变量变化时,会刷新使用该变量的组件。
@Param 组件外部输入
@Param可理解为v1版本的@Prop,但不同的是,如果单一使用@Param,则不可修改子组件当前的数据用于改变UI展示,修改时会报错,若想修改,则需要再增加一个@Once 装饰器。
@Once 初始化同步一次
增加@once 装饰器后可修改 msg 的值,会触发当前组件UI更新,但数据不会同步至父组件。需要注意:仅初始化时同步数据源一次,之后不再继续同步变化的场景。比如父组件 @Local装饰的变量存在初始值,传递给@Once装饰的变量后,再次修改@Local变量的值,子组件的值不会发生变化。
@Require
@Param默认需要设置初始值,若不想设置初始值,需要增加 @Require 装饰器。
@Event 规范组件输出
实现子组件向父组件要求更新@Param装饰变量的能力(数据双向绑定),父组件传递至子组件的数据,若子组件想修改数据并同步至父组件,则需要使用该装饰器实现。@Event装饰器只可修饰回调方法,装饰string或number等类型不报错,但也无法发挥其装饰器功能。
使用@Event和@Param实现数据双向绑定。
三、V2状态管理装饰器的优点和不足
V2的优点
- 具备深度观察、属性级更新。
- 组件中明确状态变量的输入与输出,利于组件化
- 状态变量能独立于UI存在,同一个数据被多个视图代理时,在其中一个视图的更改会通知其他视图更新
V2的不足
- 复杂对象时V1的@State能够观察复杂对象的第一层属性变化,但V2的@Local无法观察对象内部变化。为了解决这个问题,需要在类上添加@ObservedV2,并在需要观察的属性上添加@Trace。这样,框架就能追踪对象内部的属性变化。相对于V1稍微麻烦些。
- animateTo暂不支持直接在状态管理V2中使用。
