HarmonyOS开发实例:【状态管理】

 状态管理

ArkUI开发框架提供了多维度的状态管理机制,和UI相关联的数据,不仅可以在组件内使用,还可以在不同组件层级间传递,比如父子组件之间,爷孙组件之间等,也可以是全局范围内的传递,还可以是跨设备传递。另外,从数据的传递形式来看,可以分为只读的单向传递和可变更的双向传递。如下图所示,开发框架提供了多种应用程序状态管理的能力。

2_5_1

@State修饰符

@State 装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的 build() 方法刷新UI。 @State 状态数据具有以下特征:

  • 支持多种数据类型:允许 class 、 number 、 boolean 、 string 强类型的按值和按引用类型。允许这些强类型构成的数组,即Array<class>Array<string>Array<boolean>Array<number>。不允许 object 和 any

  • 内部私有:标记为 @State 的属性是私有变量,只能在组件内访问。

  • 支持多个实例:组件不同实例的内部状态数据独立。

  • 需要本地初始化:必须为所有 @State 变量分配初始值,将变量保持未初始化可能导致框架行为未定义,初始值需要是有意义的值,比如设置 class 类型的值为 null 就是无意义的,会导致编译报错。

  • 创建自定义组件时支持通过状态变量名设置初始值:在创建组件实例时,可以通过变量名显式指定 @State 状态属性的初始值。

鸿蒙OS开发更多内容↓点击HarmonyOS与OpenHarmony技术
鸿蒙技术文档开发知识更新库gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md在这

简单样例如下所示:

    @Entry @Component struct ComponentTest {@State date: string = "时间:" + new Date().getTime(); // data变化会触发build方法执行build() {Column({space: 10}) {Text(`父组件【${this.date}】`)                     // 显示时间.fontSize(20).backgroundColor(Color.Pink)Item()                                            // 子组件Item()                                            // 子组件Button('更新时间').onClick(() => {this.date = "时间:" + new Date().getTime();   // 点击按钮,date变化,会触发build方法执行})}.width('100%').height('100%').padding(10)}}// 自定义子组件@Component struct Item {@State time: string = "时间:" + new Date().getTime();build() {Text(`子组件【${this.time}】`).fontSize(20).backgroundColor(Color.Grey).onClick(() => {this.time = "时间:" + new Date().getTime();     // 点击更新时间,执行build方法})}}

样例运行结果如下图所示:

2_5_1_1

@Prop修饰符

开发应用知识已更新gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md参考前往。

@Prop 与 @State 有相同的语义,但初始化方式不同, @Prop 装饰的变量可以和父组件的 @State 变量建立单向的数据绑定。即 @Prop 修饰的变量必须使用其父组件提供的 @State 变量进行初始化,允许组件内部修改 @Prop 变量值但更改不会通知给父组件。 @Prop 状态数据具有以下特征:

  • 支持简单数据类型:仅支持 number 、 string 、 boolean 简单类型;

  • 内部私有:标记为 @Prop 的属性是私有变量,只能在组件内访问。

  • 支持多个实例:组件不同实例的内部状态数据独立。

  • 不支持内部初始化:在创建组件的新实例时,必须将值传递给 @Prop 修饰的变量进行初始化,不支持在组件内部进行初始化。

    简单样例如下所示:

    @Entry @Component struct ComponentTest {@State date: string = "时间:" + new Date().getTime();build() {Column({space: 10}) {Text(`父组件【${this.date}】`).fontSize(20).backgroundColor(Color.Pink)Item({time: this.date})                        // 必须初始化子组件的time字段Item({time: this.date})                        // 必须初始化子组件的time字段Button('更新时间').onClick(() => {this.date = "时间:" + new Date().getTime();// 父组件的更改影响子组件})}.width('100%').height('100%').padding(10)}
    }@Component struct Item {@Prop time: string;                                // 不允许本地初始化build() {Text(`子组件【${this.time}】`).fontSize(20).backgroundColor(Color.Grey).onClick(() => {this.time = "时间:" + new Date().getTime();  // 子组件的更改不影响父组件})}}

    样例运行结果如下图所示:

    2_5_2_1

@Link修饰符

@Link 与 @State 有相同的语义,但初始化方式不同, @Link 装饰的变量可以和父组件的 @State 变量建立双向的数据绑定。即 @Link 修饰的变量必须使用其父组件提供的 @State 变量进行初始化,允许组件内部修改 @Link 变量值且更改会通知给父组件。 @Link 状态数据具有以下特征:

  • 支持多种数据类型: @Link 变量的值与 @State 变量的类型相同,即 class 、 number 、 string 、 boolean 或这些类型的数组。
  • 内部私有:标记为 @Link 的属性是私有变量,只能在组件内访问。
  • 支持多个实例:组件不同实例的内部状态数据独立。
  • 不支持内部初始化:在创建组件的新实例时,必须将值传递给 @Link 修饰的变量进行初始化,不支持在组件内部进行初始化。初始化使用 $ 符号,例如:$propertiesName。

样例如下:

@Entry @Component struct ComponentTest {@State date: string = "时间:" + new Date().getTime(); // 定义@State变量build() {Column({space: 10}) {Text(`父组件【${this.date}】`).fontSize(20).backgroundColor(Color.Pink)Item({time: $date})                               // 初始化子组件time属性使用$符号Item({time: $date})                               // 初始化子组件time属性使用$符号Button('更新时间').onClick(() => {this.date = "时间:" + new Date().getTime();   // 变更date,子组件的对应属性也变化})}.width('100%').height('100%').padding(10)}
}@Component struct Item {@Link time: string;build() {Text(`子组件【${this.time}】`).fontSize(20).backgroundColor(Color.Grey).onClick(() => {this.time = "时间:" + new Date().getTime();     // 变更time,父组件的对应属性也变化})}
}

样例运行结果如下图所示:

2_5_3_1

@StorageLink修饰符

@StorageLink(key) 装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的 build() 方法进行UI刷新。组件通过使用 @StorageLink(key) 装饰的状态变量与 AppStorage 建立双向数据绑定。当创建包含 @StorageLink 的状态变量的组件时,该状态变量的值将使用 AppStorage 中的值进行初始化,在UI组件中对 @StorageLink 的状态变量所做的更改将同步到 AppStorage ,并从 AppStorage 同步到任何其他绑定实例中,如 PersistentStorage 或其他绑定的UI组件。 @StorageLink 状态数据具有以下特征:

  • 支持多种数据类型:支持的数据类型和 @State 一致且支持 object 。

  • 需要本地初始化:必须为所有 @StorageLink 变量分配初始值。

  • 数据状态全局化:使用 @StorageLink 修饰的数据变化后全局都会改变。

  • 数据持久化:通过搭配 PersistentStorage 接口实现数据持久化。

    • 绑定数据

      简单样例如下所示:

      @Entry @Component struct ComponentTest {@StorageLink('time') time: string = "1648643734154";// 使用StorageLink标记并初始化build() {Column({space: 10}) {Text(`父组件【${this.time}】`) // 使用time值.fontSize(20).backgroundColor(Color.Pink)Button('更新时间').onClick(() => {this.time = new Date().getTime().toString();// 更改time的值})}.width('100%').height('100%').padding(10)}
      }

运行结果如下图所示:

2_5_4_1

 
-   **双向绑定数据**简单样例如下所示:```@Entry @Component struct ComponentTest {@StorageLink('time') time1: string = "1648643734154";@StorageLink('time') time2: string = "abcdefefwefwewee";build() {Column({space: 10}) {Text(`父组件【${this.time1}】`).fontSize(20).backgroundColor(Color.Pink)Item();Item();Button('更新时间').onClick(() => {this.time2 = new Date().getTime().toString();})}.width('100%').height('100%').padding(10)}}@Component struct Item {@StorageLink('time') time: string = "OpenHarmony";build() {Text(`子组件【${this.time}】`).fontSize(20).backgroundColor(Color.Grey).onClick(() => {this.time = new Date().getTime().toString();})}}```

运行结果如下图所示:

2_5_4_2

  • 页面间数据绑定

简单样例如下图所示:

 
 ```// 第一个页面@Entry @Component struct ComponentTest {@StorageLink('time') time1: string = "1648643734154";// 应用key的值以首次初始化的值为准@StorageLink('time') time2: string = "abcdefefwefwewee";// time2以time1的值为准build() {Column({space: 10}) {Text(`父组件【${this.time1}】`).fontSize(20).backgroundColor(Color.Pink)Item();// 使用自定义组件Item();// 使用自定义组件Button('更新时间').onClick(() => {this.time2 = new Date().getTime().toString();// 更改time2的值,所有使用key的页面都会刷新})Button('跨页面数据绑定').onClick(() => {router.push({uri: "pages/test/setting"})// 打开第二个页面})}.width('100%').height('100%').padding(10)}}// 自定义个组件@Component struct Item {@StorageLink('time') time: string = "OpenHarmony";// time的值以key第一次出现的初始化为准build() {Text(`子组件【${this.time}】`).fontSize(20).backgroundColor(Color.Grey).onClick(() => {this.time = new Date().getTime().toString();// 更改time的值,所有使用key的页面都会刷新})}}// 第二个页面@Entry @Component struct Setting {@StorageLink('time') tips: string = "我是第二个页面"; // tips的值以'key'第一次出现的为准build() {Column({space: 10}) {Text(this.tips) // tips的值以'key'第一次出现的为准.fontSize(20).margin(20).onClick(() => {this.tips = "0000000000000" // 更改tips的值,所有使用key的页面都会更新})Button('返回').onClick(() => {router.back()// 点击返回,首页的数据会更改})}.width('100%').height('100%')}}```

运行结果如下图所示:

2_5_4_3

  • 持久化数据

@StorageLink 搭配 PersistentStorage 接口可以实现数据本地持久化,简单样例如下图所示:

 ```// 持久化存储key并设置默认值PersistentStorage.PersistProp("time", "Hello, OpenHarmony")@Entry @Component struct ComponentTest {// 初始化time1,如果AppStorage@StorageLink('time') time1: string = "1648643734154";@StorageLink('time') time2: string = "OpenHarmony";build() {Column({space: 10}) {Text(`父组件【${this.time1}】`).fontSize(20).backgroundColor(Color.Pink)Item();Item();Button('更新时间').onClick(() => {this.time2 = new Date().getTime().toString();})Button('跨页面数据绑定').onClick(() => {router.push({uri: "pages/test/setting"})})}.width('100%').height('100%').padding(10)}}// 自定义组件@Component struct Item {@StorageLink('time') time: string = "OpenHarmony";build() {Text(`子组件【${this.time}】`).fontSize(20).backgroundColor(Color.Grey).onClick(() => {this.time = new Date().getTime().toString();})}}```

运行结果如下图所示:

2_5_4_4

@Watch修饰符

@Watch 用来监听状态变量的变化,当它修饰的状态变量发生变更时,回调相应的方式,语法结构为:

@State @Watch("function_name") count : number = 0;

上述语句表示:给状态变量 count 增加一个 @Watch 装饰器,通过 @Watch 注册一个回调方法 function_name , 当状态变量 count 被改变时, 触发 function_name 回调。

简单样例如下所示:

@Entry @Component struct WatchTest {@State @Watch("onBasketUpdated") shopBasket: Array<number> = [7, 12, 47, 3];@State totalPurchase: number = 0;updateTotal(): number {let sum = 0;this.shopBasket.forEach((i) => {sum += i;});// 计算新的购物篮总价值,如果超过100RMB,则适用折扣this.totalPurchase = (sum < 100) ? sum : 0.9 * sum;return this.totalPurchase;}onBasketUpdated(propName: string): void {this.updateTotal();}build() {Column({space: 10}) {Text(`${this.totalPurchase}`).fontSize(30)Button("add to basket").onClick(() => {this.shopBasket.push(Math.round(100 * Math.random()))})}.width("100%").height("100%").padding(10)}
}

样例运行结果如下图所示:

2_5_5_1

集合 shopBasket 是一个状态变量,它被 @Watch 修饰符修饰并绑定了 onBasketUpdated() 方法回调,当点击按钮往 shopBasket 里添加数据时会触发 onBasketUpdated() 方法的调用,该方法里边执行了 totalPurchase 的数据计算,最后页面刷新。

@Watch 装饰器只能监听 @State 、 @Prop 、 @Link 、 @ObjectLink 、 @Provide 、 @Consume 、 @StorageProp 以及 @StorageLink 装饰的变量。

小结

通过对ArkUI三种状态管理的介绍,可以根据具体的业务场景选择不同的状态管理模式。

鸿蒙开发岗位需要掌握那些核心要领?

目前还有很多小伙伴不知道要学习哪些鸿蒙技术?不知道重点掌握哪些?为了避免学习时频繁踩坑,最终浪费大量时间的。

自己学习时必须要有一份实用的鸿蒙(Harmony NEXT)资料非常有必要。 这里我推荐,根据鸿蒙开发官网梳理与华为内部人员的分享总结出的开发文档。内容包含了:【ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战】等技术知识点。

废话就不多说了,接下来好好看下这份资料。

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。鸿蒙OpenHarmony知识←前往。下面是鸿蒙开发的学习路线图。

针对鸿蒙成长路线打造的鸿蒙学习文档。鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。

其中内容包含:

《鸿蒙开发基础》鸿蒙OpenHarmony知识←前往

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

《鸿蒙开发进阶》鸿蒙OpenHarmony知识←前往

  1. Stage模型入门
  2. 网络管理
  3. 数据管理
  4. 电话服务
  5. 分布式应用开发
  6. 通知与窗口管理
  7. 多媒体技术
  8. 安全技能
  9. 任务管理
  10. WebGL
  11. 国际化开发
  12. 应用测试
  13. DFX面向未来设计
  14. 鸿蒙系统移植和裁剪定制
  15. ……

《鸿蒙开发实战》鸿蒙OpenHarmony知识←前往

  1. ArkTS实践
  2. UIAbility应用
  3. 网络案例
  4. ……

最后

鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/804285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

限流的实现方式

1、tomcat 设置最大链接数 2、Nginx 漏桶算法 3、网关&#xff0c;令牌桶算法

【HTML】简单制作一个3D动态粒子效果的时空隧道

目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段HTML&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;CSS的文件名改为[Bab…

单例模式(饿汉模型,懒汉模型)

在着里我们先了解什么是单例模式。 就是某个类在进程中只能有单个实例&#xff0c;这里的单例模式需要一定的编程技巧&#xff0c;做出限制&#xff0c;一旦程序写的有问题&#xff0c;创建了多个实例&#xff0c;编程就会报错。 如果我们学会了单例模式&#xff0c;这种模式…

ubuntu下miniconda安装方式

conda官网&#xff1a; https://docs.anaconda.com/free/miniconda/ 安装方式&#xff1a; 全部执行完毕后&#xff0c;重新登录终端&#xff0c;就可以进入默认的 base 环境。 接下来可以继续使用命令创建和切换所需要的python环境 # 创建python 3.8的环境 mytest conda c…

mineadmin 设置时区

由于不同环境下&#xff0c;会造成时区不一致问题 在/bin/hyperf.php 文件里&#xff0c;设置 date_default_timezone_set(Asia/Shanghai);

qiankun 主子应用使用同一地址同一端口配置

参考官网配置链接&#xff1a;https://qiankun.umijs.org/zh/cookbook#%E5%9C%BA%E6%99%AF-1%E4%B8%BB%E5%BA%94%E7%94%A8%E5%92%8C%E5%BE%AE%E5%BA%94%E7%94%A8%E9%83%A8%E7%BD%B2%E5%88%B0%E5%90%8C%E4%B8%80%E4%B8%AA%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%90%8C%E4%B8%80%E4%B8%A…

【Java网络编程】IP网络协议与TCP、UDP网络传输层协议

1.1、IP协议 当应用层的数据被封装后&#xff0c;想要将数据在网络上传输&#xff0c;数据究竟要被发往何处&#xff0c;又该如何精准的在网络上定位目标机器&#xff0c;此时起到关键作用的就是“IP协议”。IP协议的作用在于把各种数据包准确无误的传递给目标方&#xff0c;其…

微信小程序用户登录授权指定(旧版本)

配置旧版本基础库2.12.3 实现效果 点击登录按钮即可直接登录&#xff0c;获取用户昵称和头像 点击获取头像昵称按钮则需要授权&#xff0c;才能成功登录 代码实现 my.xml <!-- 登录页面,调试基础库为2.20.2库 --> <view class"mylogin"><block w…

B02、分析GC日志-6.3

1、相关GC日志参数 -verbose:gc 输出gc日志信息&#xff0c;默认输出到标准输出-XX:PrintGC 输出GC日志。类似&#xff1a;-verbose:gc-XX:PrintGCDetails 在发生垃圾回收时打印内存回收详细的日志&#xff0c; 并在进程退出时输出当前内存各区域分配情况-XX:PrintGCTimeStamp…

XILINX 7系列时钟资源

文章目录 前言一、时钟概要1.1、CC1.2、BUFR、BUFIO、BUFMR1.3、CMT1.4、BUFH1.5、BUFG 二、时钟路由资源三、CMT 前言 本文主要参考xilinx手册ug472 一、时钟概要 7系列FPGA时钟资源主要有CC、BUFR、BUFIO、BUFMR、CMT、BUFG、BUFH和GTE_COMMON 1.1、CC “CC”&#xff0…

代码签名证书是什么?软件签名证书功能和分类

代码签名证书是什么&#xff1f;代码签名证书&#xff08;Code Signing Certificate&#xff09;是用于对可执行文件或脚本&#xff0c;软件代码等进行数字签名&#xff0c;可验证软件发布者身份、保证软件签名后未被篡改&#xff0c;以此验证开发者身份的真实性和保护代码的完…

运营商名称 是如何显示到 手机通知栏上的?

在我们日常使用手机的过程中&#xff0c;经常会在通知栏或设置菜单中看到特定的运营商名称&#xff0c;例如"中国移动"、"中国联通"或"中国电信"等。 那么&#xff0c;这些运营商的名称是如何出现在我们手机上的呢&#xff1f;手机又是如何区分不…

软信天成:如何通过5个步骤获得高层对主数据管理项目的支持

如今&#xff0c;全球各地的组织正在采用主数据管理&#xff08;MDM&#xff09;以应对日益严峻的数据问题。然而&#xff0c;成功地实现 MDM 项目并非易事&#xff0c;这需要得到高层的全力支持。下面&#xff0c;软信天成将详细介绍五步策略&#xff0c;协助您获得高层对MDM项…

SCI一区 | Matlab实现OOA-TCN-BiGRU-Attention鱼鹰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现OOA-TCN-BiGRU-Attention鱼鹰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现OOA-TCN-BiGRU-Attention鱼鹰算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述程序…

基于springboot实现常州地方旅游管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现旅游管理系统演示 摘要 随着旅游业的迅速发展&#xff0c;传统的旅游信息查询方式&#xff0c;已经无法满足用户需求&#xff0c;因此&#xff0c;结合计算机技术的优势和普及&#xff0c;针对常州旅游&#xff0c;特开发了本基于Bootstrap的常州地方旅游管…

MacOS初识SIP——解决快捷指令sh脚本报错Operation not permitted

前言 因为一些原因&#xff0c;设计了一套快捷指令&#xff0c;中间涉及到一个sh脚本的运行&#xff0c;通过快捷指令运行时就会报错&#xff1a;operation not permitted 奇怪的是在快捷指令窗口下运行一切正常&#xff0c;但是从其他地方直接调用&#xff0c;例如通过Comma…

微服务 - (狂神)

什么是微服务&#xff1a; 微服务方案&#xff1a; 1. SpringCloud NetFlix 2. Dubbo 3. SpringCloud Alibaba 解决了什么问题&#xff1a; 1. 服务过多&#xff0c;客户端怎么访问 2. 服务过多&#xff0c;服务间怎么传值 3. 服务过多&#xff0c;如何治理 4. 服务过多…

【Flutter】三个Channel(Android-java / Ios-swift)

Channel 实现与原生通信 【1】MethodChannel flutter MethodChannel官方文档 通过MethodChannel来传递数据&#xff0c;调用方法 案例 分别调用Android和Ios原生的获取电量的方法 Flutter端 实例一个MethodChannel&#xff0c; 唯一标识name&#xff0c;定义方法名称get…

JavaScript ECMAScript标准的与时俱进:从ES6至ES14的革新之路与关键技术特性剖析

ECMAScript&#xff08;通常缩写为ES&#xff09;是一种标准化的脚本语言规范&#xff0c;由ECMA International&#xff08;前身为European Computer Manufacturers Association&#xff0c;欧洲计算机制造商协会&#xff09;制定。自1997年发布首个版本以来&#xff0c;ECMAS…

设计模式之创建型模式---建造者模式

文章目录 建造者模式概述经典的建造者模式建造者模式的变种总结 建造者模式概述 建造者模式是一种广泛使用的设计模式&#xff0c;在三方开源库和各种SDK中经常见到。建造者设计模式在四人帮的经典著作《设计模式&#xff1a;可复用面向对象软件基础》中被提及&#xff0c;它的…