当前位置: 首页 > news >正文

ArkUI - 状态管理

目录

一、@State装饰器 

二、自定义组件

三、@Prop和@Link、@Provide和@Consume


一、@State装饰器 

这里涉及到两个概念 状态 视图 

  • 状态(State):指驱动视图更新的数据(就是被@State注解标记的变量)
  • 视图(View):基于UI描述渲染的得到的用户界面

简单来说,就是被@State修饰的变量如果在视图中被互动事件修改了,如果别的地方要是用到了这个变量也会同时被修改。但如果只是一个普通的变量的话视图里面不会发生任何变化(不过在底层里是被真正修改了的,只是不会触发视图更新渲染而已)。

注意:

1、@State装饰器标记的变量必须初始化,不能为空值,否则直接报错

2、@State装饰器不允许标记any、union这种复杂的类型

3、嵌套类型以及数组中的对象属性不能触发视图更新,如果真的需要实现这个情况,那么就要使用@Observed和ObjectLink注解,最后会讲到。


二、自定义组件

        ArkTS通过struct声明组件名,并通过@Component和@Entry装饰器,来构成一个自定义组件。使用@Entry和@Component装饰的自定义组件作为页面的入口,会在页面加载时首先进行渲染。

其实说白了就是把你写好的一个组件分模块封装起来,类似于Vue的组件

这里会涉及到三个注解,上一篇只是简单提及了一下

  • @Bulider:将组件封装为一个函数
  • @Extend():括号中写组件,这个是控制这个组件在这个项目中全局的样式
  • @Styles:这是将样式封装起来作为一函数

比如在这个页面中,每一个待办项其实都是相同的,复用性极高,我们可以将这个组件单独提取出来然后多次复用。

其次就是每个待办项有两种渲染状态,完成以及待办

先来看看这个部分的代码

可以看出这两个Image的实现具有大量重复代码,也就图片参数不一样,这两个图片可以在鸿蒙官网上直接下载然后放在media文件里。

最后强调一次$r("app.xxx")是查找本地资源,app是默认前缀必须携带。

@Bulider装饰器可以将组件直接封装在函数里面多次调用。

现在我们使用@Bulider将这部分重复的逻辑封装起来,然后用@Styles和@Extend将样式也封装起来。

@Component
export struct ToDoItem {@State private finished: boolean = false;private content: string = "新任务";build() {Row() {this.card(this.content)}.cardStyle().onClick(() => {this.finished = !this.finished})}@Builder card(content: string) {if (!this.finished) {Image($r("app.media.ic_screenshot_circle")).ToDoImg()Text(content).margin({ left: 20 })} else {Image($r("app.media.ic_public_todo_filled")).ToDoImg()Text(content).finishedToDo()}}@Styles cardStyle() {.backgroundColor(Color.White).width("95%").padding(20).borderRadius(15).shadow({ radius: 6, color: "#36D", offsetX: 2, offsetY: 4 }).margin(10)}
}@Extend(Text) function finishedToDo() {.margin({ left: 20 }).decoration({ type: TextDecorationType.LineThrough }).fontColor('#B1B2B1')
}@Extend(Image) function ToDoImg() {.width(20).borderRadius(10).interpolation(ImageInterpolation.High)
}

这样一个自定义组件就完成了

注意:

1、@Builder与@Styles写在struct的外面里面都可以,不过@Extent只能写在struct外面

2、如果要写在struct外面,就要像Extent一样在名字前加上function关键字

然后在另一个组件中调用,这样的话,ToDoList就是父组件了,相对的其调用的ToDoItem就是子组件

import { ToDoItem } from '../TODO/ToDoItem'
@Entry
@Component
struct  ToDoList{build(){Column(){ToDoItem({content:"An1ong"})ToDoItem({content:"完成啦!"})}}
}

效果 

 

是不是感觉代码一下子就整洁规范起来了。你也可以使用之前学到的List和ListItem,以及一些组件优化这个页面。


三、@Prop和@Link、@Provide和@Consume

父子组件之间需要数据同步时,可以使用@Porp和@Link装饰器

啥是父子组件呢?就比如我们刚才的ToDoList案例中,我们将每一个ToDoItem分离了出来,然后在总体的Entry入口ToDoList中调用,这就是父子组件。如果在父组件定义了一个变量,在子组件中是无法直接调用获取的(当然你专门写个方法传递也是可以的)

这两个注解的区别是:

单向传递意思就是父组件将数据传递给子组件之后,子组件的这个数据发生改变时不会导致父组件的视图刷新。而双向同步之后子组件的这个数据发生变化之后就会同步给父组件导致视图刷新。

再以我们刚才的ToDoList案例举例,现在要实现点击子组件完成任务并同步至视图

父组件中传递参数时要使用 $ 变量 的这种格式才能传递

 子组件中就要使用@Link修饰并且不能初始化一个值了

至于@Provide和@Consume,这个是用来跨组件使用的。比如@Link和@Prop是父子关系使用,而@Provide和@Consume就不只是父子关系了,你可以多层关系使用,爷孙组件,祖宗和祖孙组件直接使用。

而且使用也不用自己传递参数了,就比如把这个案例中修改为@Provide和@Consume就需要做一些小小的修改

父组件中使用@Provide代替@State,并且调用子组件时不需要传递被修饰的变量

 子组件中将@Link改为@Consume

 

可以达到同样的效果,并且看起来更方便了,不需要自己去传递参数也不用考虑跨了多少组件的问题

那么,古尔丹,代价是什么呢? 

本来直接传递就行了,现在又要在底层帮你维护。这样势必会造成大量的资源浪费。

所以除非是真的需要用到跨组件传递,否则只是父子组件的话还是尽量还是使用@Link直接去传递参数。


@ObjectLink和@Observed装饰器用于在涉及嵌套对象数组元素对象的场景中进行双向数据同步

@Observed修饰于对象类上

@ObjectLink修饰于变量

我们曾在一开始将@State的时候就说过,使用@State修饰的变量如果是嵌套类型以及数组中的对象属性的话就不能触发视图更新。

因此我们需要使用别的注解来解决这个问题

例如我现在有一个对象类Person

class Person{name:stringage:numbergirlFriend:Personconstructor(name: string, age: number, girlFriend ?: Person) {this.name = name;this.age = age;this.girlFriend = girlFriend;}
}

可以看到改变了对象内部嵌套的对象的属性被不会触发更新视图

因此使用方法为

在对象类上加上@Observed注解,然后创建一个新的组件,间接传入对象嵌套的那个对象作为参数

@Entry
@Component
struct Parent{@State p:Person = new Person('An1ong',21,new Person('KeQing',18))build(){Column(){Child({p:this.p.gf})}.width("100%").height("100%").justifyContent(FlexAlign.Center)}
}@Component
struct Child{@ObjectLink private p:Person;build(){Text(`${this.p.name} : ${this.p.age}`).fontSize(30).onClick(() => {this.p.name = "Mona"console.log("对象内部嵌套的对象的属性已经发生了改变");})}
}@Observed
class Person{name:stringage:numbergf:Personconstructor(name: string, age: number, gf ?: Person) {this.name = name;this.age = age;this.gf = gf;}
}

相关文章:

ArkUI - 状态管理

目录 一、State装饰器 二、自定义组件 三、Prop和Link、Provide和Consume 四、Observed和ObjectLink 一、State装饰器 这里涉及到两个概念 状态 和 视图 状态(State):指驱动视图更新的数据(就是被State注解标记的变量&…...

C++ 学习系列 -- C++ 中的多态行为

一 多态是什么? 多态是面向对象三大特征中重要一项,另外两项分别是封装与继承。 所谓多态,指的是多种不同的形态,也就是去完成某个具体的行为,多个不同的对象去操作同一个函数时,会产生不同的行为&…...

Spring Cloud中实现Feign声明式服务调用客户端

可以通过OpenFeign从一个服务中调用另一个服务,我们一般采用的方式就是定义一个Feign接口并使用FeignClient注解来进行标注,feign会默认为我们创建的接口生成一个代理对象。 当我们在代码中调用Feign接口的方法的时候,实际上就是在调用我们Fe…...

【网络编程】网络通信基础——简述TCP/IP协议

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程的一点学习心得,欢迎大家在评论区交流讨论💌 目录 一、ip地…...

观察者模式 Observer

观察者模式属于行为型模式。在程序设计中,观察者模式通常由两个对象组成:观察者和被观察者。当被观察者状态发生改变时,它会通知所有的观察者对象,使他们能够及时做出响应。 三要素:观察者(Observer&#…...

Hadoop入门学习笔记——七、Hive语法

视频课程地址:https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接:https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记(汇总) 目录 七、Hive语法7.1. 数据库相关操作7.1.1. 创建数据库7.1.2…...

采用SpringBoot框架+原生HTML、JS前后端分离模式开发和部署的电子病历编辑器源码(电子病历评级4级)

概述: 电子病历是指医务人员在医疗活动过程中,使用医疗机构信息系统生成的文字、符号、图表、图形、数据、影像等数字化信息,并能实现存储、管理、传输和重现的医疗记录,是病历的一种记录形式。 医院通过电子病历以电子化方式记录患者就诊的信息,包括&…...

HTML表单

<!DOCTYPE html> <html><head><meta charset"utf-8"><title>招聘案列</title></head><body><h1>午睡操场传来蝉的声音</h1><hr /><form>昵称&#xff1a;<input type"text" …...

Http 请求体和响应体中重要的字段

Http 请求体 Accept&#xff1a;用于告诉服务器客户端能够处理哪些媒体类型。Accept 头中的值通常是一个或多个 MIME 类型&#xff0c;并按优先级排序。服务器会根据 Accept 头中的值来决定响应的内容类型。例如&#xff0c;Accept: text/plain, text/html。Content-Type&…...

最新国内可用使用GPT4.0,GPT语音对话,Midjourney绘画,DALL-E3文生图

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和用户进行创作交流。 然而&#xff0c;GP…...

【量化金融】证券投资学

韭菜的自我修养 第一章&#xff1a; 基本框架和概念1.1 大盘底部形成的技术条件1.2 牛市与熊市1.3 交易系统1.3.1 树懒型交易系统1.3.2 止损止损的4个技术 第二章&#xff1a;证券家族4兄弟2.1 债券&#xff08;1&#xff09;债券&#xff0c;是伟大的创新&#xff08;2&#x…...

【Bash】重点总结

文章目录 1. 总体认识1.1. Shell概述1.2. 第一个Shell脚本 2. 变量2.1. 定义变量2.2. 使用变量2.3. 只读变量2.4. 删除变量2.5. 变量类型2.5.1. 字符串变量 1. 总体认识 1.1. Shell概述 Shell是一个用C语言编写的程序&#xff0c;这个程序提供了一个界面&#xff0c;用户通过…...

Git安装和使用教程,并以gitee为例实现远程连接远程仓库

文章目录 1、Git简介及安装2、使用方法2.1、Git的启动与配置2.2、基本操作2.2.1、搭建自己的workspace2.2.2、git add2.2.3、git commit2.2.4、忽略某些文件不予提交2.2.5、以gitee为例实现git连接gitee远程仓库来托管代码 1、Git简介及安装 版本控制&#xff08;Revision cont…...

Hadoop入门学习笔记——一、VMware准备Linux虚拟机

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 一、VMware准备Linux虚拟机1.1. VMware安装Linux虚拟机1.…...

CSS3新增特性

CSS3 CSS3私有前缀 W3C 标准所提出的某个CSS 特性&#xff0c;在被浏览器正式支持之前&#xff0c;浏览器厂商会根据浏览器的内核&#xff0c;使用私有前缀来测试该 CSS 特性&#xff0c;在浏览器正式支持该 CSS 特性后&#xff0c;就不需要私有前缀了。 查询 CSS3 兼容性的网…...

Unity中Shader观察空间推导

文章目录 前言一、本地空间怎么转化到观察空间二、怎么得到观察空间的基向量1、Z轴向量2、假设 观察空间的 Y~假设~ (0,1,0)3、X Y 与 Z 的叉积4、Y X 与 Z 的叉积 三、求 [V~world~]^T^1、求V~world~2、求[V~world~]^T^ 四、求出最后在Unity中使用的公式1、偏移坐标轴2、把…...

信息学奥赛一本通2034:【例5.1】反序输出

2034&#xff1a;【例5.1】反序输出 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 79280 通过数: 35643 【题目描述】 输入nn个数,要求程序按输入时的逆序把这nn个数打印出来&#xff0c;已知整数不超过100100个。也就是说&#xff0c;按输入相反顺序打印这nn个…...

使用教程之【SkyWant.[2304]】路由器操作系统,破解移动【Netkeeper】校园网【小白篇】

许多高校目前饱受Netkeeper认证的痛苦&#xff0c;普通路由器无法使用&#xff0c; 教你利用SkyWant的Netkeeper认证软件来使你的SkyWant路由器顺利认证上网&#xff0c;全宿舍又可以合作共赢了&#xff01; 步骤一&#xff1a;正确连接网线&#xff0c;插电开机 正确连接网…...

模式识别与机器学习(十):梯度提升树

1.原理 提升方法实际采用加法模型&#xff08;即基函数的线性组合&#xff09;与前向分步算法。以决策树为基函数的提升方法称为提升树&#xff08;boosting tree&#xff09;。对分类问题决策树是二叉分类树&#xff0c;对回归问题决策树是二叉回归树。提升树模型可以表示为决…...

《剑指offer》Java版--12.矩阵中的路径(DFS+剪枝)

剑指offer原题:矩阵中的路径 请设计一个函数&#xff0c;用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始&#xff0c;每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格&#xff0c;那么该路径不能再…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

VUE3 ref 和 useTemplateRef

使用ref来绑定和获取 页面 <headerNav ref"headerNavRef"></headerNav><div click"showRef" ref"buttonRef">refbutton</div>使用ref方法const后面的命名需要跟页面的ref值一样 const buttonRef ref(buttonRef) cons…...

AI书签管理工具开发全记录(十八):书签导入导出

文章目录 AI书签管理工具开发全记录&#xff08;十八&#xff09;&#xff1a;书签导入导出1.前言 &#x1f4dd;2.书签结构分析 &#x1f4d6;3.书签示例 &#x1f4d1;4.书签文件结构定义描述 &#x1f523;4.1. ​整体文档结构​​4.2. ​核心元素类型​​4.3. ​层级关系4.…...