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 状态管理开发范例
本文转载自《#2023 盲盒码 # OpenHarmony 应用 ArkUI 状态管理开发范例》,作者:zhushangyuan_ 本文根据橘子购物应用,实现 ArkUI 中的状态管理。 在声明式 UI 编程框架中,UI 是程序状态的运行结果,用户构建了一个 UI …...
二、QTableWidget 类 clear() 和 clearContents() 的区别及程序崩溃原因分析
问题描述:区分 QTableWidget 类的 clear() 和 clearContents() 的用法,以及可能由于这两个方法使用不当导致程序崩溃的原因分析 Qt 官方文档对 QTableWidget 类的 clear() 方法描述如下: [slot] void QTableWidget::clear() Removes all ite…...
spring boot 项目中搭建 ElasticSearch 中间件 一 postman 操作 es
postman 操作 es 1. 简介2. 环境3. postman操作索引3.1 创建索引3.2 查看索引3.3 查看所有索引3.4 删除索引 4. postman操作文档4.1 添加文档4.2 查询文档4.3 查询全部文档4.4 更新文档4.5 局部更新文档4.6 删除文档4.7 条件查询文档14.8 条件查询文档24.9 条件查询文档 limit4…...
设计模式—观察者模式(Observer)
目录 思维导图 一、什么是观察者模式? 二、有什么优点吗? 三、有什么缺点吗? 四、什么时候使用观察者模式? 五、代码展示 ①、双向耦合的代码 ②、解耦实践一 ③、解耦实践二 ④、观察者模式 六、这个模式涉及到了哪些…...
分类算法系列③:模型选择与调优 (Facebook签到位置预测)
目录 模型选择与调优 1、介绍 模型选择(Model Selection): 调优(Hyperparameter Tuning): 本章重点 2、交叉验证 介绍 为什么需要交叉验证 数据处理 3、⭐超参数搜索-网格搜索(Grid Search) 介绍…...
PCL RANSAC分割提取多个空间圆
目录 一、概述二、代码实现三、结果展示1、原始数据2、提取结果四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、概述 使用PCL分割提取多个空间圆,其核心原理仍然是RANSAC拟合空间圆,这里只是做简单修改…...
Java八股文学习笔记day01
01.和equals区别 对于字符串变量来说,使用""和"equals"比较字符串时,其比较方法不同。""比较两个变量本身的值,即两个对象在内存中的首地址,"equals"比较字符串包含内容是否相同。 对于非…...
vant的NavBar导航栏可以自定义背景图片吗
可以的,Vant的NavBar导航栏提供了一个background-image属性,可以设置自定义背景图片。例 如: <van-nav-bar title"标题" left-text"返回" left-arrow background-image"url(https://example.com/image.jpg)&qu…...
深入浅出AXI协议(5)——数据读写结构读写响应结构
目录 一、前言 二、写选通(Write strobes) 三、窄传输(Narrow transfers) 1、示例1 2、示例2 四、字节不变性(Byte invariance) 五、未对齐的传输(Unaligned transfers) 六…...
IntelliJ Idea开发Vue遇到的几个问题
IntelliJ Idea开发Vue遇到的几个问题 确保 idea已安装插件【Vue.js】 问题1:ts方法错误 或 提示导入 import xxx.vue标红 解决办法:在 env.d.ts中添加以下代码(若无此文件,重新创建): /* eslint-disable */ declare module *.…...
sql查找最晚一天/日期最大的一条记录 两种方法
例:查找最晚入职员工的所有信息 建表: CREATE TABLE employees ( emp_no int(11) NOT NULL, birth_date date NOT NULL, first_name varchar(14) NOT NULL, last_name varchar(16) NOT NULL, gender char(1) NOT NULL, hire_date date NOT NULL, PRIMA…...
详解python的
详解& 在Python中,使用&符号可以求取两种数据类型的交集: 集合(Set):你可以使用&来计算两个集合的交集。例如: set1 {1, 2, 3, 4} set2 {3, 4, 5, 6} common_elements set1 & set2 pri…...
Modbus TCP通信笔记
目录 1 Modbus TCP 数据协议1.1 数据格式1.2 报文头(MBAP头)1.3 功能码1.4 Modbus 地址映射到 CPU 地址 2 Modbus TCP 通讯数据示例2.1 功能码01 读离散输出线圈2.2 功能码02 读离散输入线圈2.3 功能码03 读保持寄存器2.4 功能码04 读输入寄存器2.5 功能码05 写单个离散输出寄存…...
CIM和websockt-实现实时消息通信:双人聊天和消息列表展示
欢迎大佬的来访,给大佬奉茶 一、文章背景 有一个业务需求是:实现一个聊天室,我和对方可以聊天;以及有一个消息列表展示我和对方(多个人)的聊天信息和及时接收到对方发来的消息并展示在列表上。 项目框架概…...
useLayoutEffect和useEffect有什么作用?
useEffect 和 useLayoutEffect 都是 React 中的钩子函数,用于在组件渲染过程中执行副作用操作。它们的主要区别在于执行时机。 useEffect: useEffect 是异步执行的,它在浏览器渲染完成之后才执行。这意味着它不会阻塞浏览器的渲染过程,因此适合用于处理副作用,如数据获取、…...
django中配置使用websocket终极解决方案
django ASGI/Channels 启动和 ASGI/daphne的区别 Django ASGI/Channels 是 Django 框架的一个扩展,它提供了异步服务器网关接口(ASGI)协议的支持,以便处理实时应用程序的并发连接。ASGI 是一个用于构建异步 Web 服务器和应用程序…...
敦煌网、Jumia等跨境电商平台怎么测评(补单)留评?
评论的重要性是众所周知的,对于想要做卖家运营的人来说,它直接影响着产品的销量和排名 那么如何通过自养号测评来提升销量和排名呢? 我相信大家对这个问题已经有了一定的了解,拥有大量自养号可以通过这些号来通过关键词搜索、浏…...
uni-app之android离线打包
一 AndroidStudio创建项目 1.1,上一节演示了uni-app云打包,下面演示怎样androidStudio离线打包。在AndroidStudio里面新建空项目 1.2,下载uni-app离线SDK,离线SDK主要用于App本地离线打包及扩展原生能力,SDK下载链接h…...
【传输层】TCP -- 三次握手四次挥手 | 可靠性与提高性能策略
超时重传机制连接管理机制三次握手四次挥手滑动窗口拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况TCP小结基于TCP应用层协议理解 listen 的第二个参数 超时重传机制 主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B࿱…...
前端将UTC时间格式转化为本地时间格式~~uniapp写法
UTC时间格式是什么 首先我们先简单的了解一下:UTC时间(协调世界时,Coordinated Universal Time)使用24小时制,以小时、分钟、秒和毫秒来表示时间 HH:mm:ss.SSSHH 表示小时,取值范围为00到23。mm 表示分钟…...
说说Kappa架构
分析&回答 对于实时数仓而言,Lmabda架构有很明显的不足,首先同时维护两套系统,资源占用率高,其次这两套系统的数据处理逻辑相同,代码重复开发。 能否有一种架构,只需要维护一套系统,就可以…...
项目介绍:《Online ChatRoom》网页聊天室 — Spring Boot、MyBatis、MySQL和WebSocket的奇妙融合
在当今数字化社会,即时通讯已成为人们生活中不可或缺的一部分。为了满足这一需求,我开发了一个名为"WeTalk"的聊天室项目,该项目基于Spring Boot、MyBatis、MySQL和WebSocket技术,为用户提供了一个实时交流的平台。在本…...
Vue3 学习 组合式API setup语法糖 响应式 指令 DIFF(一)
文章目录 前言一、Composition Api二、setup语法糖三、响应式refreactive 四、其他一些关键点v-prev-oncev-memov-cloak 五、虚拟Dom五、diff算法 前言 本文用于记录学习Vue3的过程 一、Composition Api 我觉得首先VUE3最大的改变就是对于代码书写的改变,从原来选择…...
一文轻松入门DeepSort
1.背景 Deepsort是目标检测任务的后续任务,得益于Yolo系列的大放异彩,DeepSort目标追踪任务的精度也不断提高,同时,DeepSort属于目标追踪任务中的多目标追踪,即MOT(Multiple Object Tracking,M…...
关于linux openssl的自签证书认证与nginx配置
自签文档链接 重点注意这块,不能写一样的,要是一样的话登录界面锁会报不安全 域名这块跟最后发布的一致 nginx配置的话 server {listen 443 ssl; //ssl 说明为https 默认端口为443server_name www.skyys.com; //跟openssl设置的域名保持一致s…...
Mybatis--关联关系映射
目录: 1.什么是关联关系映射: 一对一和多对多的区别 2.mybaits中的一对一&一对多关联关系配置 配置generatoeConfig文件 插件自动生成 编辑 写sql语句 创建 Ordermapper类 编写接口类 编辑 编写接口实现类 编写测试类 测试结果 一对…...
Golang基本的网络编程
Go语言基本的Web服务器实现 Go 语言中的 http 包提供了创建 http 服务或者访问 http 服务所需要的能力,不需要额外的依赖。 Go语言在Web服务器中主要使用到了 “net/http” 库函数,通过分析请求的URL来实现参数的接收。 下面介绍了http 中Web应用的基本…...
Postgresql的一个bug_涉及归档和pg_wal
故障描述: 服务器ocmpgdbprod1,是流复制主节点,它的从节点是ocmpgdbprod2,两个节点的Postgresql数据库版本都是PostgreSQL 11.6,主节点ocmpgdbprod1配置了pg_wal归档,从节点ocmpgdbprod2没有配置pg_wal归档…...
轻量、便捷、高效—经纬恒润AETP助力车载以太网测试
随着自动驾驶技术和智能座舱的不断发展,高宽带、高速率的数据通信对主干网提出了稳定、高效的传输要求,CAN(FD)、LIN已无法充分满足汽车的通信需求。车载以太网作为一种快速且扩展性好的网络技术,已经逐步成为了汽车主干网的首选。 此外&…...
【跟小嘉学 Rust 编程】二十四、内联汇编(inline assembly)
系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...
wordpress wpml 下载/浏览器网址
开始前先介绍一下我们的Qt商业控件: QtitanRibbon| 下载试用: 遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,致力于为Windows、Linux和Mac OS X提供功能完整的Ribbon组件。QtitanChart | 下载试用 :是一个C 库,代表一组控件…...
银川网站建设就找湖海/营销策略都有哪些
2.4、依赖注入的三种方式 我们在Spring配置文件中引入的bean初始值是空的,依赖注入就是给他们赋值。这里主要介绍三种常用的方式。 1、setter注入 <bean id"student" class"com.lu.Spring.pojo.Student"><property name"id"…...
企石做网站/昆山网站建设推广
台积电遭遇罕见的病毒攻击,虽然其声称各工厂已快速恢复生产,不过作为全球最大的芯片代工厂这必然会对其客户产生较大的影响,那么哪些芯片企业将会受到影响,对其客户又会造成怎么样的深远影响呢?台积电的工艺制程产能将…...
什么样的蓝色做网站做好看/aso优化违法吗
改问题是"babel-eslint"版本更新问题导致的; 给大家一个最简单粗暴的解决方案: 在项目里找到对应的工程:直接删除里面的node_modules文件夹,然后重新npm install下就可以了; node_modules文件内容较多&#…...
招聘网站做鸭子的/小广告图片
1.题目描述 Implement int sqrt(int x). Compute and return the square root of x. 2.解法分析 很明显,用二分搜索可解,但是需要防止溢出,所以中间结果和上界下界都要用long long 来保存。 class Solution { public: int sqrt(int x) { // S…...
服务商英文/河北seo基础知识
Unity Shader的组织形式 Unity Shader的形态 Unity官方手册上讲Unity Shader有三种不同的编写方案,这三种编写方案分别是surface shaders、vertex and fragment shaders和fixed function shaders。 从前面几篇笔记中可以了解到,可编程图形管线中能够编写…...