HarmonyOS 角落里的知识 —— 状态管理

2024-06-19 02:52

本文主要是介绍HarmonyOS 角落里的知识 —— 状态管理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 一、前言

在探索 HarmonyOS 的过程中,我们发现了许多有趣且实用的功能和特性。有些总是在不经意间或者触类旁通的找到。或者是某些开发痛点。其中,状态管理是ArkUI开发非常核心的一个东西,我们进行了大量的使用和测试遇到了许多奇奇怪怪的问题。

该系列将着重分享、介绍HarmonyOS API11+的新版本特性或者奇奇怪怪的解决方案、BUG。(弃用API非必要不提及)

二、@State

这应该是用的最多的了,状态变量,将状态变量和UI的某个属性绑定,即可同步两者。

  1. 初始化行为

    组件初始化时,@State只能从外面传入一次,之后父组件值的修改并不会影响到组件内部的@State,所以它叫组件内状态~(当然你组件用if、else来更新当我没说)

 @Entry@Componentexport struct ExpComponent {@State title: string = "Title"​build() {Column() {ExpChildComponent({childTitle: this.title})Button(this.title).onClick(()=>{this.title = "Click"})}}}@Componentexport struct ExpChildComponent {@State childTitle: string = "????"​build() {Text(this.childTitle)}}
  1. 就像这样,onClick触发后ExpChildComponent并不会发生改变了。

  2. 太多的@State

    1. 一开始我们会直接将状态变量直接声明在组件中,如:
 @Componentexport struct ExpComponent {@State title: string = ""​build() {Text(this.title)}}

但是随着,一个页面开始变得复杂的时候,我们会面临一堆的Controller,xxState等等,看起来就很头疼。这时候利用@State能观察到Object.keys(自身)返回的所有属性的特性,我们可以抽出一个ExpUIState

 @Componentexport struct ExpComponent {@State uiState: ExpUIState = new ExpUIState()​build() {Text(this.uiState.title)}}​class ExpUIState {title: string = ""}
  1. 如此,还你一个优雅的组件。

  2. 数组

    @State能直接修饰数组:

 @State title: Model[] = [new Model(1), new Model(2)];

数组自身的赋值可以观察到。

 this.title = [new Model(2)];

数组项的赋值可以观察到。

 this.title[0] = new Model(2);

删除数组项可以观察到。

 this.title.pop();

新增数组项可以观察到。

 this.title.push(new Model(12));

数组项中属性的赋值观察不到。

this.title[0].value = 6;
  • 数组对象及其子项的赋值是可以被观察到的,所以“titles[0].value = 1 ”这种使用方法是没用滴。

    4.作用域的影响

  • 得益于闭包的特性(对于Java、Kotlin开发来说不存在的东西)箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。

    @Component
    export struct ExpComponent {@State uiState: ExpUIState = new ExpUIState()build() {Column() {Text(this.uiState.title)Button("Click").onClick(()=>{this.uiState.autoRefreshTitle()})}}
    }
    class ExpUIState {title: string = "??"autoRefreshTitle = () => {this.title = "AutoRefreshTitle"}
    }
    

    上述操作,触发onClick是不会更新UI的,如果想要触发更新需要用下面的例子:

@Component
export struct ExpComponent {@State uiState: ExpUIState = new ExpUIState()aboutToAppear(): void {}build() {Column() {Text(this.uiState.title)Button("Click").onClick(()=>{let fk = this.uiStatethis.uiState.autoRefreshTitle(fk)})}}
}
class ExpUIState {title: string = "??"autoRefreshTitle = (st:ExpUIState) => {st.title= "AutoRefreshTitle"}
}
  1. 反人类吧?阿弥陀佛。

  2. 嵌套对象

    @State修饰对象时,里面可能还有对象,或者数组.

class ExpUIState {childs: ExpChild[] = []firstChild: ExpChild = new ExpChild()
}
  1. 很可惜的是,由于@State装饰的变量,只能监听到对象本身的地址以及第一层属性的地址变化,也就是firstChild或者childs地址的变化,例如如下操作:uiState.firstChild.subTtile="",uiState.childs.push(new ExpChild())等是没法触发刷新的。

    解决办法就是不用@State

三、@Prop

  1. 初始化行为

    几乎和@State一致,但是@Prop变量允许在本地修改,但修改后的变化不会同步回父组件。当数据源更改时,@Prop装饰的变量都会更新,并且会覆盖本地所有更改。因此,数值的同步是父组件到子组件(所属组件),子组件数值的变化不会同步到父组件。

    相比起@State重点就是父组件修改后子组件会同步。苦恼@State没法修改的人,有福了~

  2. 套一堆的@Prop

    不要这么做。如果你的子组件使用@Prop、孙子组件也用@Prop,我其实推荐你使用@Provide(当然你硬要用也行)

  3. @Require

    使用@Prop有一个好处就是,可以使用@Require。变成一个必传的参数(福音啊)。@State是可以不传的。

@Require @Prop index: number 

Observed

坏消息:@Prop也没法观察嵌套对象~,因为父组件传入时,用的@State传入的。好消息:加一个@Observed就好了~

@Component
export struct ExpComponent {@State uiState: ExpUIState = new ExpUIState()aboutToAppear(): void {}build() {Column() {ExpChildComponent({child: this.uiState.firstChild})Button("Click").onClick(() => {this.uiState.firstChild.subTitle = "????"})}}
}@Component
export struct ExpChildComponent {@Require @Prop child: ExpChildbuild() {Text(this.child.subTitle)}
}@Observed
class ExpUIState {childs: ExpChild[] = []firstChild: ExpChild = new ExpChild()
}@Observed
class ExpChild {subTitle: string = "啊"
}

在嵌套场景下,每一层都要用@Observed装饰,且每一层都要被@Prop接收。

四、@Link

  1. 初始化行为

    @Link装饰的变量与其父组件中的数据源共享相同的值

    PS:从API version 9开始,@Link子组件从父组件初始化@State的语法为Comp({ aLink: this.aState })。同样Comp({aLink: $aState})也支持(早该如此了)

  2. 给Dialog用

    如果你在某个Dialog中,想同步数据到组件,@Link是一个很好的选择:

 @CustomDialogstruct CustomDialog01 {@Link inputValue: string;controller: CustomDialogController;​build() {Column() {Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })TextInput({ placeholder: '', text: this.inputValue }).height(60).width('90%').onChange((value: string) => {this.inputValue = value;})}}}​@Entry@Componentstruct DialogDemo01 {@State inputValue: string = 'click me';dialogController: CustomDialogController = new CustomDialogController({builder: CustomDialog01({inputValue: $inputValue})})​build() {Column() {Button(this.inputValue).onClick(() => {this.dialogController.open();}).backgroundColor(0x317aff)}.width('100%').margin({ top: 5 })}}
  1. 当然,你也可以传个函数进去~

  2. @Link套娃

    就像@Prop一样,我很建议你使用@Provide@Consume

五、@Watch

@Watch应用于对状态变量的监听,这个装饰器可以说是非常直观的一个了,就是用来观察状态变量的。

  1. 不要在里面修改状态变量

 @State @Watch("onUiStateChange") uiState: ExpUIState = new ExpUIState()onUiStateChange(){this.uiState.firstChild = new ExpChild()}
  • 相信你看得出来,这是一个死循环吧?

  • 子组件事件传递到父组件

    可通过状态同步@Link@Provide@Consume进行父子组件间的状态通知,结合@Watch可以将状态变量的修改在组件间传递,实现类似的功能。

  • 粘性

    @Watch没有粘性,所以第一次初始化并不会触发@Watch!

  • 日志

    @Watch可以观察状态变量变化的特性,很适合来做Log日志不是吗~



最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

鸿蒙HarmonyOS Next全套学习资料←点击领取!(安全链接,放心点击

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

鸿蒙(HarmonyOS NEXT)最新学习路线

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

HarmonyOS Next 最新全套视频教程

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

大厂面试必问面试题

鸿蒙南向开发技术

鸿蒙APP开发必备

鸿蒙生态应用开发白皮书V2.0PDF



获取以上完整鸿蒙HarmonyOS学习资料,请点击→

总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

这篇关于HarmonyOS 角落里的知识 —— 状态管理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1073809

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

hdu1565(状态压缩)

本人第一道ac的状态压缩dp,这题的数据非常水,很容易过 题意:在n*n的矩阵中选数字使得不存在任意两个数字相邻,求最大值 解题思路: 一、因为在1<<20中有很多状态是无效的,所以第一步是选择有效状态,存到cnt[]数组中 二、dp[i][j]表示到第i行的状态cnt[j]所能得到的最大值,状态转移方程dp[i][j] = max(dp[i][j],dp[i-1][k]) ,其中k满足c

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;