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可以观察嵌套场景,其他的状态变量仅能观察第一层,详情见各个装饰器章节的"观察变化和行为表现"小节。

相关推荐
写雨.010 小时前
鸿蒙定位开发服务
华为·harmonyos·鸿蒙
goto_w15 小时前
uniapp上使用webview与浏览器交互,支持三端(android、iOS、harmonyos next)
android·vue.js·ios·uni-app·harmonyos
别说我什么都不会1 天前
ohos.net.http请求HttpResponse header中set-ccokie值被转成array类型
网络协议·harmonyos
码是生活1 天前
鸿蒙开发排坑:解决 resourceManager.getRawFileContent() 获取文件内容为空问题
前端·harmonyos
鸿蒙场景化示例代码技术工程师1 天前
基于Canvas实现选座功能鸿蒙示例代码
华为·harmonyos
小脑斧爱吃鱼鱼1 天前
鸿蒙项目笔记(1)
笔记·学习·harmonyos
鸿蒙布道师1 天前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
zhang1062091 天前
HarmonyOS 基础组件和基础布局的介绍
harmonyos·基础组件·基础布局
马剑威(威哥爱编程)1 天前
在HarmonyOS NEXT 开发中,如何指定一个号码,拉起系统拨号页面
华为·harmonyos·arkts
GeniuswongAir1 天前
Flutter极速接入IM聊天功能并支持鸿蒙
flutter·华为·harmonyos