【中秋国庆不断更】OpenHarmony组件内状态变量使用:@State装饰器
@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。
在状态变量相关装饰器中,@State是最基础的,使变量拥有状态属性的装饰器,它也是大部分状态变量的数据源。
说明:
从API version 9开始,该装饰器支持在ArkTS卡片中使用。
概述
@State装饰的变量,与声明式范式中的其他被装饰变量一样,是私有的,只能从组件内部访问,在声明时必须指定其类型和本地初始化。初始化也可选择使用命名参数机制从父组件完成初始化。
@State装饰的变量拥有以下特点:
- @State装饰的变量与子组件中的@Prop、@Link或@ObjectLink装饰变量之间建立单向或双向数据同步。
- @State装饰的变量生命周期与其所属自定义组件的生命周期相同。
装饰器使用规则说明
| @State变量装饰器 | 说明 |
| 装饰器参数 | 无 |
| 同步类型 | 不与父组件中任何类型的变量同步。 |
| 允许装饰的变量类型 | Object、class、string、number、boolean、enum类型,以及这些类型的数组。 支持Date类型。 支持类型的场景请参考观察变化。 类型必须被指定。 不支持any,不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。 说明: 不支持Length、ResourceStr、ResourceColor类型,Length、ResourceStr、ResourceColor为简单类型和复杂类型的联合类型。 |
| 被装饰变量的初始值 | 必须本地初始化。 |
变量的传递/访问规则说明
| 传递/访问 | 说明 |
| 从父组件初始化 | 可选,从父组件初始化或者本地初始化。如果从父组件初始化将会覆盖本地初始化。 支持父组件中常规变量(常规变量对@Prop赋值,只是数值的初始化,常规变量的变化不会触发UI刷新,只有状态变量才能触发UI刷新)、@State、@Link、@Prop、@Provide、@Consume、@ObjectLink、@StorageLink、@StorageProp、@LocalStorageLink和@LocalStorageProp装饰的变量,初始化子组件的@State。 |
| 用于初始化子组件 | @State装饰的变量支持初始化子组件的常规变量、@State、@Link、@Prop、@Provide。 |
| 是否支持组件外访问 | 不支持,只能在组件内访问。 |
图1 初始化规则图示

观察变化和行为表现
并不是状态变量的所有更改都会引起UI的刷新,只有可以被框架观察到的修改才会引起UI刷新。该小节去介绍什么样的修改才能被观察到,以及观察到变化后,框架的是怎么引起UI刷新的,即框架的行为表现是什么。
观察变化
- 当装饰的数据类型为boolean、string、number类型时,可以观察到数值的变化。
// for simple type
@State count: number = 0;
// value changing can be observed
this.count = 1; - 当装饰的数据类型为class或者Object时,可以观察到自身的赋值的变化,和其属性赋值的变化,即Object.keys(observedObject)返回的所有属性。例子如下。 声明ClassA和Model类。
class ClassA {public value: string;constructor(value: string) {this.value = value;}}class Model {public value: string;public name: ClassA;constructor(value: string, a: ClassA) {this.value = value;this.name = a;}}
@State装饰的类型是Model
// class类型
@State title: Model = new Model('Hello', new ClassA('World'));
对@State装饰变量的赋值。
// class类型赋值
this.title = new Model('Hi', new ClassA('ArkUI'));
对@State装饰变量的属性赋值。
// class属性的赋值
this.title.value = 'Hi'
嵌套属性的赋值观察不到。
// 嵌套的属性赋值观察不到
this.title.name.value = 'ArkUI'
- 当装饰的对象是array时,可以观察到数组本身的赋值和添加、删除、更新数组的变化。例子如下。 声明ClassA和Model类。
class Model {public value: number;constructor(value: number) {this.value = value;}
}
@State装饰的对象为Model类型数组时。
@State title: Model[] = [new Model(11), new Model(1)]
数组自身的赋值可以观察到。
this.title = [new Model(2)]
数组项的赋值可以观察到。
this.title[0] = new Model(2)
删除数组项可以观察到。
this.title.pop()
新增数组项可以观察到。
this.title.push(new Model(12))
- 当装饰的对象是Date时,可以观察到Date整体的赋值,同时可通过调用Date的接口setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime, setUTCFullYear, setUTCMonth, setUTCDate, setUTCHours, setUTCMinutes, setUTCSeconds, setUTCMilliseconds 更新Date的属性。
@Entry
@Component
struct DatePickerExample {@State selectedDate: Date = new Date('2021-08-08')build() {Column() {Button('set selectedDate to 2023-07-08').margin(10).onClick(() => {this.selectedDate = new Date('2023-07-08')})Button('increase the year by 1').margin(10).onClick(() => {this.selectedDate.setFullYear(this.selectedDate.getFullYear() + 1)})Button('increase the month by 1').margin(10).onClick(() => {this.selectedDate.setMonth(this.selectedDate.getMonth() + 1)})Button('increase the day by 1').margin(10).onClick(() => {this.selectedDate.setDate(this.selectedDate.getDate() + 1)})DatePicker({
start: new Date('1970-1-1'),
end: new Date('2100-1-1'),
selected: this.selectedDate})}.width('100%')}
}
框架行为
- 当状态变量被改变时,查询依赖该状态变量的组件;
- 执行依赖该状态变量的组件的更新方法,组件更新渲染;
- 和该状态变量不相关的组件或者UI描述不会发生重新渲染,从而实现页面渲染的按需更新。
使用场景
装饰简单类型的变量
以下示例为@State装饰的简单类型,count被@State装饰成为状态变量,count的改变引起Button组件的刷新:
- 当状态变量count改变时,查询到只有Button组件关联了它;
- 执行Button组件的更新方法,实现按需刷新。
@Entry
@Component
struct MyComponent {
@State count: number = 0; build() {
Button(`click times: ${this.count}`)
.onClick(() => {
this.count += 1;
})
}
}
装饰class对象类型的变量
- 自定义组件MyComponent定义了被@State装饰的状态变量count和title,其中title的类型为自定义类Model。如果count或title的值发生变化,则查询MyComponent中使用该状态变量的UI组件,并进行重新渲染。
- EntryComponent中有多个MyComponent组件实例,第一个MyComponent内部状态的更改不会影响第二个MyComponent。
class Model {public value: string;constructor(value: string) {this.value = value;}
}@Entry
@Component
struct EntryComponent {build() {Column() {// 此处指定的参数都将在初始渲染时覆盖本地定义的默认值,并不是所有的参数都需要从父组件初始化MyComponent({ count: 1, increaseBy: 2 })MyComponent({ title: new Model('Hello, World 2'), count: 7 })}}
}@Component
struct MyComponent {@State title: Model = new Model('Hello World');@State count: number = 0;private increaseBy: number = 1;build() {Column() {Text(`${this.title.value}`)Button(`Click to change title`).onClick(() => {// @State变量的更新将触发上面的Text组件内容更新this.title.value = this.title.value === 'Hello ArkUI' ? 'Hello World' : 'Hello ArkUI';})Button(`Click to increase count=${this.count}`).onClick(() => {// @State变量的更新将触发该Button组件的内容更新this.count += this.increaseBy;})}}
}
从该示例中,我们可以了解到@State变量首次渲染的初始化流程:
- 使用默认的本地初始化:
@State title: Model = new Model('Hello World');
@State count: number = 0;
2.对于@State来说,命名参数机制传递的值并不是必选的,如果没有命名参数传值,则使用本地初始化的默认值:
class C1 {public count:number;public increaseBy:number;constructor(count: number, increaseBy:number) {this.count = count;this.increaseBy = increaseBy;}
}
let obj = new C1(1, 2)
MyComponent(obj)
相关文章:
【中秋国庆不断更】OpenHarmony组件内状态变量使用:@State装饰器
State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。 在状态变量相关装饰器中,State是最基础的,使变量拥有状态属性的装饰器&am…...
【Java 进阶篇】MySQL多表关系详解
MySQL是一种常用的关系型数据库管理系统,它允许我们创建多个表格,并通过各种方式将这些表格联系在一起。在实际的数据库设计和应用中,多表关系是非常常见的,它能够更好地组织和管理数据,实现数据的复杂查询和分析。本文…...
【开发篇】十、Spring缓存:手机验证码的生成与校验
文章目录 1、缓存2、用HashMap模拟自定义缓存3、SpringBoot提供缓存的使用4、手机验证码案例完善 1、缓存 缓存是一种介于数据永久存储介质与数据应用之间的数据临时存储介质使用缓存可以有效的减少低速数据读取过程的次数(例如磁盘IO),提高…...
【Aurora 8B/10B IP(1)--初步了解】
Aurora 8B/10B IP(1)–初步了解 1 Aurora 8b/10b IP的基本状态: •通用数据通道吞吐量范围从480 Mb/s到84.48 Gb/s •支持多达16个连续粘合7GTX/GTH系列、UltraScale™ GTH或UltraScale+™ GTH收发器和4绑定GTP收发器 •Aurora 8B/10B协议规范v2.3顺从的 •资源成本低(请参…...
C++ vector容器的介绍与使用
一、vector简介 std::vector 是 C 标准模板库 (STL) 中的一个动态数组容器。允许存储元素(可以使用任何数据类型作为其元素类型)集合,并能够动态调整其大小。 特点: 动态大小:与常规数组不同,vector 可以…...
openstack的组成
OpenStack 是一个开源的云计算平台,由一系列组件构成,各组件之间相互协作,提供了完整的基础设施即服务(IaaS)解决方案。下面详细解释了 OpenStack 的主要组件及其相互关系: Nova(计算服务&…...
[React] React高阶组件(HOC)
文章目录 1.Hoc介绍2.几种包装强化组件的方式2.1 mixin模式2.2 extends继承模式2.3 HOC模式2.4 自定义hooks模式 3.高阶组件产生初衷4.高阶组件使用和编写结构4.1 装饰器模式和函数包裹模式4.2 嵌套HOC 5.两种不同的高阶组件5.1 正向的属性代理5.2 反向的继承 6.如何编写高阶组…...
【逐步剖C++】-第二章-C++类和对象(中)
前言:本章继【逐步剖C】-第二章-C类和对象(上)介绍有关类和对象更深层次的知识点,这里是文章导图: 本文较长,内容较多,大家可以根据需求跳转到自己感兴趣的部分,希望能对读者有一些帮…...
PL/SQL动态SQL
目录 1. 动态 sql 2. 带参数的动态 sql -- 不使用 USING 传参 1. 动态 sql -- 在 PL/SQL 程序开发中,可以使用 DML 语句,但是很多语句(如 DDL),不能直接在 PL/SQL中执行,这些语句可以使用动态 sql 来实现. 语法格式: EXECUTE IMMEDIATE --动态语句的字符串 [into 变量…...
Python绘图系统24:添加辅助坐标轴
文章目录 辅助坐标增减坐标轴时间轴**代码优化源代码 Python绘图系统: 前置源码: Python打造动态绘图系统📈一 三维绘图系统 📈二 多图绘制系统📈三 坐 标 轴 定 制📈四 定制绘图风格 📈五 数据…...
Java自学网站--十几个网站的分析与评测
原文网址:Java自学网站--十几个网站的分析与评测_IT利刃出鞘的博客-CSDN博客 简介 很多想学Java的人不知道怎样选教程,本文对Java自学网站进行评测。 本文不带主观倾向,只客观分析各个网站的区别。 第1类:大型培训机构(黑马等…...
java接口怎么写
Java接口是一种定义规范的抽象类型,可以包含常量和方法的声明。接口在Java编程中具有重要的作用,可以实现代码的重用和灵活性。本文将详细介绍Java接口的编写方式和使用方法。 一、什么是Java接口 在Java中,接口(Interface&…...
第8章 Spring(二)
8.11 Spring 中哪些情况下,不能解决循环依赖问题 难度:★★ 重点:★★ 白话解析 有一下几种情况,循环依赖是不能解决的: 1、原型模式下的循环依赖没办法解决; 假设Girl中依赖了Boy,Boy中依赖了Girl;在实例化Girl的时候要注入Boy,此时没有Boy,因为是原型模式,每次都…...
从0开始python学习-24.selenium 浏览器常见的操作
1. 浏览器的最大化/最小化:maximize_window () / minimize_window() 2. 设置浏览器的宽高:set_window_size() 3. 设置浏览器的位置:set_window_position(0,0) —》左上角为原点 4. 刷新:refresh() 5. 前进:forward() 6…...
Canal实现数据同步
1、Canal实现数据同步 canal可以用来监控数据库数据的变化,从而获得新增数据,或者修改的数据。 1.1 Canal工作原理 原理相对比较简单: 1、canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送…...
数据库学习笔记——DDL
数据库学习笔记——DDL 建立EMPLOYEE数据库: CREATE TABLE employee(employee_ID int not null,employee_name varchar(20) not null,street varchar(20) not null,city varchar(20) not null,PRIMARY KEY(employee_ID) );CREATE TABLE company(company_name varc…...
MATLAB算法实战应用案例精讲-【人工智能】边缘计算(附python代码实现)
目录 前言 几个高频面试题目 边缘计算和云计算的关系 云计算(cloud computing) 边缘计算...
精彩回顾 | 迪捷软件亮相2023世界智能网联汽车大会
2023年9月24日,2023世界智能网联汽车大会(以下简称大会)在北京市圆满落幕。迪捷软件北京参展之行圆满收官。 本次大会由工业和信息化部、公安部、交通运输部、中国科学技术协会、北京市人民政府联合主办,是我国首个经国务院批准的…...
【ShaderLab PBR 嗜血边缘角色_美式朋克风格_“Niohoggr“_角色渲染(第一篇)】
嗜血边缘角色Cyberpunk style Unity 渲染 《嗜血边缘》截取其中的片段如下:资源分析其中Guitar贴图4张模型:人物细节图:人物模型 Inspector面板这里做一个区域区分:Body贴图1_BC贴图1_BC属性:Body贴图2_NBody贴图3_CMBody贴图4_SRMBody贴图4_RGBReflection Probe第一版Sha…...
python经典百题之围圈报数
题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。 程序分析 思路1:模拟游戏过程 使用一个循环队列模拟游戏过程,每次循…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
