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 装饰的变量与其父组件中的数据源共享相同的值。

@Componentexport struct DetailPage {  @State currentLocation: string = ''}

在父组件 DetailPage 中声明当前定位 currentLocation 变量

Panel(this.isPanel) {    Location({ isPanel: $isPanel, currentLocation: $currentLocation })}

将 currentLocation 变量传给子组件 Location

@Componentexport 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@Componentstruct 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@Componentexport 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@Componentstruct 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 initgit config core.sparsecheckout trueecho code/Solutions/Shopping/OrangeShopping/ > .git/info/sparse-checkoutgit remote add origin https://gitee.com/openharmony/applications_app_samples.gitgit pull origin master

参考资料

橘子购物示例应用

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

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

相关文章

MySQL8.xx 解决1251 client does not support ..解决方案

MySQL8.0.30一主两从复制与配置(一)_蜗牛杨哥的博客-CSDN博客 MySQL8.xx一主两从复制安装与配置 MySQL8.XX随未生成随机密码解决方案 一、客户端连接mysql,问题:1251 client does not support ... 二、解决 1.查看用户信息 备注:host为 % …

Git和Github的基本用法

目录 背景 下载安装 安装 git for windows 安装 tortoise git 使用 Github 创建项目 注册账号 创建项目 下载项目到本地 Git 操作的三板斧 放入代码 三板斧第一招: git add 三板斧第二招: git commit 三板斧第三招: git push 小结 🎈个人主页&#xf…

iOS开发Swift-3-UI与按钮Button-摇骰子App

1.创建新项目Dice 2.图标 删去AppIcon,将解压后的AppIcon.appiconset文件拖入Assets包。 3.将素材点数1-6通过网页制作成2x,3x版本并拖入Asset。 4.设置对应的UI。 5.拖入Button组件并设置style。 6.Ctrl加拖拽将Button拖拽到ViewController里&#xff0…

5G NR:RACH流程 -- Msg1之选择正确的PRACH时频资源

PRACH的时域资源是如何确定的 PRACH的时域资源主要由参数“prach-ConfigurationIndex”决定。拿着这个参数的取值去协议38211查表6.3.3.2-2/3/4,需要注意根据实际情况在这三张表中进行选择: FR1 FDD/SULFR1 TDDFR2 TDD Random access preambles can onl…

Python实现多子图绘制系统

文章目录 修改DrawTypeDrawType的调用逻辑绘图逻辑源代码 Python绘图系统: 📈从0开始的3D绘图系统📉一个3D坐标系,多个函数图表类型和风格:📉极坐标绘图📊散点图和条形图📊混合类型…

【LeetCode75】第四十三题 钥匙和房间

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 给我们一个数组,表示对应的房间里拥有能开启的对应索引号的钥匙。 一开始我们只能进入0号房间,也就是数组里索引…

SpringBoot集成WebSocket

SpringBoot集成WebSocket 项目结构图 项目架构图 前端项目 socket.js 注意前端这里的端口是9000, 路劲是ws开头 function createScoket(token){var socket;if(typeof(WebSocket) "undefined") {console.log("您的浏览器不支持WebSocket");}else{var ho…

linux C++ 海康截图Demo

项目结构 CMakeLists.txt cmake_minimum_required(VERSION 3.7)project(CapPictureTest)include_directories(include)link_directories(${CMAKE_SOURCE_DIR}/lib ${CMAKE_SOURCE_DIR}/lib/HCNetSDKCom) add_executable(CapPictureTest ${CMAKE_SOURCE_DIR}/src/CapPictureTes…

小兔鲜儿 - 地址模块

目录 小兔鲜儿 - 地址模块 准备工作​ 静态结构​ 地址管理页​ 地址表单页​ 动态设置标题​ 新建地址页​ 接口封装​ 参考代码​ 地址管理页​ 接口调用​ 参考代码​ 修改地址页​ 数据回显​ 更新地址​ 表单校验​ 操作步骤​ 删除地址​ 侧滑组件用法…

dji uav建图导航系列()ROS中创建dji_sdk节点包(一)项目结构

文章目录 1、整体项目结构1.1、 目录launch1.2、文件CMakeLists.txt1.3、文件package.xml1.4、目录include1.4、目录srv在ROS框架下创建一个无人机的节点dji_sdk,实现必需的订阅(控制指令)、发布(无人机里程计)、服务(无人机起飞降落、控制权得很)功能,就能实现一个类似…

基于java Swing 和 mysql实现的飞机订票系统(源码+数据库+ppt+ER图+流程图+架构说明+论文+运行视频指导)

一、项目简介 本项目是一套基于java Swing 和 mysql实现的飞机订票系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、项目文档、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过…

myspl使用指南

mysql数据库 使用命令行工具连接数据库 mysql -h -u 用户名 -p -u表示后面是用户名-p表示后面是密码-h表示后面是主机名,登录当前设备可省略。 如我们要登录本机用户名为root,密码为123456的账户: mysql -u root -p按回车,然后…

【0901作业】QTday3 对话框、发布软件、事件处理机制,使用文件相关操作完成记事本的保存功能、处理键盘事件完成圆形的移动

目录 一、思维导图 二、作业 2.1 使用文件相关操作完成记事本的保存功能 2.2 处理键盘事件完成圆形的移动 一、思维导图 二、作业 2.1 使用文件相关操作完成记事本的保存功能 void Widget::on_saveBtn_clicked() {QString filename QFileDialog::getSaveFileName(this,&…

目录扫描+JS文件中提取URL和子域+403状态绕过+指纹识别(dirsearch_bypass403)

dirsearch_bypass403 在安全测试时,安全测试人员信息收集中时可使用它进行目录枚举,目录进行指纹识别,枚举出来的403状态目录可尝试进行绕过,绕过403有可能获取管理员权限。不影响dirsearch原本功能使用 运行流程 dirsearch进行…

【狂神】Spring5笔记(10-19)

又是美好而努力的一天呀~ __ /|* * * * * * / * * * / * * * * / * * * * * * * happy valentines day * * * * …

自然语言处理-NLP

目录 自然语言处理-NLP 致命密码:一场关于语言的较量 自然语言处理的发展历程 兴起时期 符号主义时期 连接主义时期 深度学习时期 自然语言处理技术面临的挑战 语言学角度 同义词问题 情感倾向问题 歧义性问题 对话/篇章等长文本处理问题 探索自然语言…

电脑莫名其妙重启 为设备 ROOT\DISPLAY\0000 加载驱动程序 \Driver\WUDFRd 失败

卸载向日葵即可解决!!!!!下面是报错日志,估计是远程连接导致的问题

JVM工具-1. jps 虚拟机进程状态工具

文章目录 1. jps介绍2. jps命令格式3. jps工具主要选项4. jps -q5. jps -m6. jps -l7. jps -v 1. jps介绍 jps(JVM Process Status Tool):虚拟机进程状态工具,可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class&…

ARM寄存器组

CM3 拥有通用寄存器 R0‐R15 以及一些特殊功能寄存器。 R0-R7,通用目的寄存器 R0-R7也被称为低组寄存器,所有指令可以访问它们,它们的字长为32位,复位后的初始值是不可预料的。 R8-R12,通用目的寄存器 R8-R12也被称…

汽车以太网协议栈

《大师说》栏目上线啦# 《大师说》栏目是怿星科技2023年推出的深度思考栏目,通过邀请内部专家,针对智能汽车行业发展、技术趋势等输出个性化的观点。每期一位大师,每位一个话题,本期由我们怿星的CTO虞胜伟,进行分享。…