HarmonyOS入门-状态管理

View(UI):UI渲染,指将build方法内的UI描述和@Builder装饰的方法内的UI描述映射到界面。

State:状态,指驱动UI更新的数据。用户通过触发组件的事件方法,改变状态数据。状态数据的改变,引起UI的重新渲染。


装饰器

ArkUI状态管理V1提供了多种装饰器,通过使用这些装饰器,状态变量不仅可以观察在组件的改变,还可以在不同组件层级间传递,如父子组件、跨组件层级,也可以观察全局范围内的变化 。

1.1根据变量影响范围,分为

1.管理组件拥有状态的装饰器:组伯级别的状态管理,可以观察组件内的变化,和不同的组件层级的变化,但需要唯一观察同一个组件树上,就是同一个界面。

2.管理应用拥有状态的装饰器:应用级别的状态管理,可以观察不同的页面,或者不同的UIAbility的变化,是应用内全局的状态管理。

1.2从数据传递形式和同步类型层面上看,分为

1.只读的单向传递

2.可变的双向传递

2.装饰器(关键词)

@State: @State装饰的变量拥有其所属组件的状态,可以作为其子组件单向和双向同步的数据源。当其数值改变时,会引起相关的渲染刷新
  • @Prop:@Prop装饰的变量可以和父组件建立单向同步关系,@Prop装饰的变量是可变的,但修改不会同步回父组件。
Matlab 复制代码
####@State

# 父组件

@State passMsg:string = '传递给子组件的信息'

# 调用子组件sonComponent
sonComponent({msg: this.passMsg}) # 把passMsg传递给子组件

------------------------------------------------------------

####@Prop
# 子组件

@Prop msg:string # 使用@Prop装饰器接收父组件传入的信息

Text(this.msg) # 渲染父组件传入的信息
  • @Link:@Link装饰的变量可以和父组件建立双向同步关系,子组件中@Link装饰变量的修改会同步给父组件中建立双向数据绑定的数据源,父组件的更新也会同步给@Link装饰的变量。@link 区别于@Prop的地方就在于,@Link会双向绑定更新
Matlab 复制代码
####@State

# 父组件

@State passMsg:string = '传递给子组件的信息'

Text(this.passMsg) # 同时会跟着子组件数据的变化而变化
# 调用子组件linkSonComponent
linkSonComponent({msg: $passMsg}) # 把passMsg传递给子组件, 传递信息的方式要使用 $ 修饰符

------------------------------------------------------------

####@Link
# 子组件

@Link msg:string # 使用@Link装饰器接收父组件传入的信息

Button(this.msg) # 渲染父组件传入的信息
  .onClick(() => {
      this.msg = 'hello world' # 子组件数据变化,父组件数据也会变化
  })

我理解@Link 和 @Prop区别的地方在于,一个是操作的是拷贝出来的对象,一个是操作的对象的地址,即对象本身。

  • @provide/@Consume:@Provide/@Consume装饰的变量用于跨组件层级(多层组件)同步状态变量,可以不需要通过参数命名机制传递,通过alias(别名)或者属性名绑定。

~~~关键字行为

1.初始渲染:

  • @Provide装饰的变量会以map的形式,传递给当前@Provide所属组件的所有子组件;
  • 子组件中如果使用@Consume变量,则会在map中查找是否有该变量名/alias(别名)对应的@Provide的变量,如果查找不到,框架会抛出JS ERROR;
  • 在初始化@Consume变量时,和@State/@Link的流程类似,@Consume变量会在map中查找到对应的@Provide变量进行保存,并把自己注册给@Provide。

2.当@Provide装饰的数据变化时:

  • 通过初始渲染的步骤可知,子组件@Consume已把自己注册给父组件。父组件@Provide变量变更后,会遍历更新所有依赖它的系统组件(elementid)和状态变量(@Consume);
  • 通知@Consume更新后,子组件所有依赖@Consume的系统组件(elementId)都会被通知更新。以此实现@Provide对@Consume状态数据同步。

3.当@Consume装饰的数据变化时:

  • 通过初始渲染的步骤可知,子组件@Consume持有@Provide的实例。在@Consume更新后调用@Provide的更新方法,将更新的数值同步回@Provide,以此实现@Consume向@Provide的同步更新。
  • @Observed:@Observed装饰class,需要观察多层嵌套场景的class需要被@Observed装饰。单独使用@Observed没有任何作用,需要和@ObjectLink、@Prop联用。
  • @ObjectLink:@ObjectLink装饰的变量接收@Observed装饰的class的实例,应用于观察多层嵌套场景,和父组件的数据源构建双向同步。

@Observed 首先是针对对象使用的不管是class对象,,或者struct对象。

@Observed声明对象范围,@ObjectLink或者@Prop声明实例后对象指针的类型。

Matlab 复制代码
this.objLink.a = ... #允许修改


this.objLink = ... #不允许修改,想要修改的话,objLink需要使用@Prop关键词修饰,拷贝。

框架行为

  • 初始渲染:

@Observed装饰的class的实例会被不透明的代理对象包装,代理了class上的属性的settergetter方法

子组件中@ObjectLink装饰的从父组件初始化,接收被@Observed装饰的class的实例,@ObjectLink的包装类会将自己注册给@Observed class。

  • 属性更新:当@Observed装饰的class属性改变时,会走到代理的setter和getter,然后遍历依赖它的@ObjectLink包装类,通知数据更新。
    !说明

@Observed/@ObjectLink可以观察嵌套场景,其他的状态变量仅能观察第一层,详情见各个装饰器章节的"观察变化和行为表现"小节。

相关推荐
coder_pig1 小时前
跟🤡杰哥一起学Flutter (三十四、玩转Flutter手势✋)
前端·flutter·harmonyos
simple丶2 小时前
【HarmonyOS】鸿蒙蓝牙连接与通信技术
harmonyos·arkts·arkui
前端世界3 小时前
HarmonyOS开发实战:鸿蒙分布式生态构建与多设备协同发布全流程详解
分布式·华为·harmonyos
Jalor4 小时前
Flutter + 鸿蒙 | Flutter 跳转鸿蒙原生界面
flutter·harmonyos
zhanshuo5 小时前
开发者必看!如何在HarmonyOS中快速调用摄像头功能
harmonyos
HMSCore5 小时前
借助HarmonyOS SDK,《NBA巅峰对决》实现“分钟级启动”到“秒级进场”
harmonyos
zhanshuo5 小时前
鸿蒙UI开发全解:JS与Java双引擎实战指南
前端·javascript·harmonyos
HarmonyOS小助手6 小时前
闯入鸿蒙:浪漫、理想与「草台班子」
harmonyos·鸿蒙·harmonyos next·鸿蒙生态
xq95276 小时前
flutter 鸿蒙化插件开发横空出世
harmonyos
HarmonyOS_SDK6 小时前
借助HarmonyOS SDK,《NBA巅峰对决》实现“分钟级启动”到“秒级进场”
harmonyos