OpenHarmony应用ArkUI 状态管理开发范例
本文转载自《#2023盲盒+码# OpenHarmony应用ArkUI 状态管理开发范例》,作者:zhushangyuan_
本文根据橘子购物应用,实现ArkUI中的状态管理。
在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染,在ArkUI中统称为状态管理机制。
自定义组件拥有变量,变量必须被装饰器装饰才可以成为状态变量,状态变量的改变会引起UI的渲染刷新。如果不使用状态变量,UI只能在初始化时渲染,后续将不会再刷新。 下图展示了State和View(UI)之间的关系。

管理组件拥有的状态
@State装饰器:组件内状态
@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。
在状态变量相关装饰器中,@State是最基础的,使变量拥有状态属性的装饰器,它也是大部分状态变量的数据源。
@link装饰器:父子双向同步
子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。
@Link装饰的变量与其父组件中的数据源共享相同的值。
@Component
export struct DetailPage {
@State currentLocation: string = ''
}
在父组件DetailPage中声明当前定位currentLocation变量
Panel(this.isPanel) {
Location({ isPanel: $isPanel, currentLocation: $currentLocation })
}
将currentLocation变量传给子组件Location
@Component
export struct Location {
@Link currentLocation: string
}
子组件用@Link装饰的currentLocation接收。
@Builder cityList(city: any) {
if (this.currentLocation === city.name) {
List() {
ForEach(city.city, twoCity => {
ListItem() {
Column() {
Text(`${twoCity}`)
.width('100%')
.height(30)
.fontSize(14)
.onClick(() => {
this.currentLocation = city.name + '/' + twoCity
})
}
}
})
}
.width('100%')
.divider({ strokeWidth: 2, color: $r('app.color.divider'), startMargin: 0, endMargin: 20 })
}
}
子组件中的currentLocation变量改变会同步父组件中的currentLocation。
管理应用拥有的状态
AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。
和LocalStorage不同的是,LocalStorage是页面级的,通常应用于页面内的数据共享。而对于AppStorage,是应用级的全局状态共享。AppStorage使用场景和相关的装饰器:@StorageProp和@StorageLink
@StorageProp
@StorageProp(key)是和AppStorage中key对应的属性建立单向数据同步,我们允许本地改变的发生,但是对于@StorageProp,本地的修改永远不会同步回AppStorage中,相反,如果AppStorage给定key的属性发生改变,改变会被同步给@StorageProp,并覆盖掉本地的修改。
@Entry
@Component
struct HomePage {
@State curBp: string = 'md' // curBp指当前窗口断点,sm代表小屏,md代表中屏,lg代表大屏
}
在Home.ets页面中,用@State声明当前窗口类型:curBp变量并赋初值为md,代表中屏。
isBreakpointSM = (mediaQueryResult) => {
if (mediaQueryResult.matches) {
this.curBp = 'sm'
AppStorage.SetOrCreate('curBp', this.curBp)
}
}
isBreakpointMD = (mediaQueryResult) => {
if (mediaQueryResult.matches) {
this.curBp = 'md'
AppStorage.SetOrCreate('curBp', this.curBp)
}
}
isBreakpointLG = (mediaQueryResult) => {
if (mediaQueryResult.matches) {
this.curBp = 'lg'
AppStorage.SetOrCreate('curBp', this.curBp)
}
}
根据屏幕尺寸,将curBp设置为相应的值,并用SetOrCreate()方法保存在AppStorage中。
在子组件NavigationHomePage中直接使用curBp变量
@Entry
@Component
export struct NavigationHomePage {
@StorageProp('curBp') curBp: string = 'sm'
}
curBp是根据窗口的尺寸判断的,是不能改变的,因此使用@StorageProp(‘curBp’)与AppStorage(‘curBp’)建立单向数据同步。
@StorageLink
@StorageLink(key)是和AppStorage中key对应的属性建立双向数据同步:
1. 本地修改发生,该修改会被同步回AppStorage中;
2. AppStorage中的修改发生后,该修改会被同步到所有绑定AppStorage对应key的属性上,包括单向(@StorageProp和通过Prop创建的单向绑定变量)、双向(@StorageLink和通过Link创建的双向绑定变量)变量和其他实例(比如PersistentStorage)。
@Entry
@Component
struct HomePage {
@StorageLink('shoppingCartGoodsList') shoppingCartGoodsList: { data: { id: number } }[] = []
}
在Home.ets页面中,用@StorageLink装饰器定义shoppingCartGoodsList,用于获取全局的购物车商品列表。
this.emitterClass.setShoppingCartGoodsList((eventData)=>{
this.shoppingCartGoodsList.push(eventData.data.id)
AppStorage.SetOrCreate('shoppingCartGoodsList', this.shoppingCartGoodsList)
})
使用AppStorage.SetOrCreate(‘shoppingCartGoodsList’, this.shoppingCartGoodsList)将购物车商品列表保存在AppStorage中。
因为购物车中的商品会联动的变化,比如在商品的详情页将商品添加至购物车,在首页也需要更新购物车信息,因此购物车商品列表采用@StorageLink装饰器装饰,与AppStorage(‘shoppingCartGoodsList’)建立双向同步。
运行测试效果
执行以下命令,可以下载橘子购物应用工程:
git init
git config core.sparsecheckout true
echo code/Solutions/Shopping/OrangeShopping/ > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master
参考资料
OpenHarmony应用ArkUI 状态管理开发范例的更多相关文章
- linux 文件系统的管理 (硬盘) 工作原理
一.系统在初始化时如何识别硬盘 1.系统初始时根据MBR的信息来识别硬盘,其中包括了一些执行文件就来载入系统,这些执行文件就是MBR里前面446bytes里的boot loader 程式,而后面的16 ...
- android shape总结 和控制的风格定制
1:shape总结 1):shape文件是放置在drawable文件下的.res/drawable/filename.xml. 2):shape类型:android:shape. 一共同拥有四种:re ...
- Kafka 处理器客户端介绍
[编者按]本文作者为 Bill Bejeck,主要介绍如何有效利用新的 Apache Kafka 客户端来满足数据处理需求.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正文. 如果你 ...
- [转]Windows服务“允许服务与桌面交互”的使用和修改方法
上一篇文章是纯 C# 代码的形式勾上 “允许服务与桌面交互” 选项的 本文转载自:http://blog.csdn.net/lanruoshui/article/details/4756408 描述: ...
- 信号处理篇alarm ferror kill mkfifo pause pclose perror pipe popen sigaction sigaddset sigdelset sigemptyset signal sleep strerror
alarm(设置信号传送闹钟) 相关函数 signal,sleep 表头文件 #include<unistd.h> 定义函数 unsigned int alarm(unsigned int ...
- linux文件系统管理的工作原理
一.系统在初始化时如何识别硬盘 1.系统初始时根据MBR的信息来识别硬盘,其中包括了一些执行文件就来载入系统,这些执行文件就是MBR里前面446bytes里的boot loader 程式,而后面的16 ...
- Linuxx学习-特殊文件与进程
具有 SUID/SGID 权限的指令执行状态 SUID 的权限其实与进程的相关性非常的大!为什么呢?先来看看 SUID 的程序是如何被一般用户 执行,且具有什么特色呢? SUID 权限仅对二进制程序( ...
- 零元学Expression Blend 4 - Chapter 7 什麽?影片不再是印象中的方框框!!!看Blend 4如何把影片镶入字里
原文:零元学Expression Blend 4 - Chapter 7 什麽?影片不再是印象中的方框框!!!看Blend 4如何把影片镶入字里 本章将教大家如何在Blend 4里新增Media El ...
- Arduino函数
输入输出函数 pinMode(pin, mode)将数位脚位(digital pin)指定为输入或输出.如:pinMode(7,INPUT); // 将脚位 7 设定为输入模式 digitalWrit ...
- OpenHarmony 3.1 Beta 版本关键特性解析——ArkUI canvas组件
(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 江英杰 华为技术有限公司 canvas 是 ArkUI 开发框架里的画布组件,常用于自定义绘制图形.因为其轻量.灵活. ...
随机推荐
- RK3568开发笔记(二):入手RK3568开发板的套件介绍、底板介绍和外设测试
前言 本篇主要介绍RK3568芯片和入手开发板的底板介绍以及开发板的外设. 开发板 笔者的开发板是全套+10.1寸屏. 开发板实物 开发板资源 开发版本提供资料 开发 ...
- 泛型类Generic注解
在 Python 的 typing 模块中,Generic 是一个泛型类,用于创建参数化的类和函数,以便支持不同类型的参数.它允许你定义具有类型参数的类,这些类型参数在实例化时才确定.这样,你可以在不 ...
- git 多系统复用账号
重装系统前请备份~/.ssh下的公钥私钥文件,重装系统后,请使用以下方法复用好之前的key 将备份好的key copy至~/.ssh下 将私钥id_rsa的文件属性改为600:sudo chmod 6 ...
- EF Invalid column name 'Discriminator' Invalid column name 'TagCode'.
参考资料:Invalid column name 'TagCode'. 该异常和Discriminator没关系,一般原因:1.数据库中字段和实体类字段不一致导致的2.创建新增继承于数据库对应的实体类 ...
- 记录一个错误:Unable to find a match: python-dev
今天尝试在Linux下运行一个Python项目,在安装requirements.txt时报错 执行命令如下: [root@VM-16-8-centos cve-search]# pip3 instal ...
- 【LeetCode回溯算法#01】图解组合问题
组合问题 力扣题目链接(opens new window) 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合. 示例: 输入: n = 4, k = 2 输出: [ [2 ...
- 浅谈 rxgo 在项目中的使用方式
项目中使用到了 RxGo ,感觉现有的处理方式有一定的优势,当然也有一定的有劣势,遂记录下来,免得自己忘记. 本文介绍的只是 rxgo 的一种方式而已,如果你有不错的使用方式,请不吝赐教,谢谢. 对 ...
- Vue3基础知识提炼
1.{{}} data2.""等同{{}},数据单向绑定v-bind: 简化 :3.v-if v-else4.v-for="(i, index) in array&quo ...
- 【Azure 应用服务】NodeJS项目部署在App Service For Linux环境中,部署完成后应用无法访问
问题描述 NodeJS项目部署在App Service For Linux环境中,部署完成后应用无法访问,在启动日志中发现错误消息:ERROR - Container XXX_0 for site X ...
- TensorFlow 回归模型
TensorFlow 回归模型 首先,导入所需的库和模块.代码中使用了numpy进行数值计算,matplotlib进行数据可视化,tensorflow进行机器学习模型的构建和训练,sklearn进行多 ...