harmony OS NEXT–状态管理器–@State详解

news/2025/3/24 2:53:43/文章来源:https://www.cnblogs.com/yihonghh/p/18785290

鸿蒙Harmony--状态管理器--@State详解

1.1 定义

@State装饰的变量,或者称为状态变量,一旦变量拥有了状态属性,就可以触发其直接绑定UI组件的刷新。当状态改变时,UI会发生对应的渲染变化 ,@State装饰的变量,与声明式范式中的其他被装饰变量一样,是私有的,只能从组件内部访问。在声明时候必须本地初始化

1.1.1 案例演示

  1. 代码示意
import { promptAction } from '@kit.ArkUI'@Entry
@Component
struct Test {num: number = 1build() {Column() {Row({space:20}) {Button('+').onClick(()=>{this.num++promptAction.showToast({message:this.num+''})})Text(this.num + '')Button('-').onClick(()=>{this.num--promptAction.showToast({message:this.num+''})})}}.width('100%').height('100%')}
}
  1. 演示

如下图显示,点击Button按钮,UI界面并不会更新,但是我们通过弹层提示是可以明显看到数据变化了的,

img

  1. 加上@State装饰器后的正确效果
import { promptAction } from '@kit.ArkUI'@Entry
@Component
struct Test {@Statenum: number = 1build() {Column() {Row({space:20}) {Button('+').onClick(()=>{this.num++promptAction.showToast({message:this.num+''})})Text(this.num + '')Button('-').onClick(()=>{this.num--promptAction.showToast({message:this.num+''})})}}.width('100%').height('100%')}
}

img

通过上述案例,我们可以得出结论,@State装饰器修饰的数据变化可以让UI发生变化,但是在鸿蒙中,@State装饰器也有限制。在修饰引用数据的时候,@State装饰器只能监测对象自身和第一层的变化

1.2@State装饰器的限制以及解决办法

1.2.1限制

@State修饰引用类型的数据时候,只能在自身或者第一层发生变化的时候产生更新

  1. 案例
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Test01 {//1.数据驱动UI变化  加上@State装饰器@StatepersionInfo: PersionInfo = {name: '小程',age: '21',sex: '女',address: {province: '安徽',city: '黄山市',area: '黄山'}}build() {Column() {Row() {Text('姓名:')TextInput({ text: this.persionInfo.name }).layoutWeight(1)}.width('100%').padding(20)Row() {Text('年龄:')TextInput({ text: this.persionInfo.age }).layoutWeight(1)}.width('100%').padding(20)Row() {Text('性别:')TextInput({ text: this.persionInfo.sex }).layoutWeight(1)}.width('100%').padding(20)Row({ space: 10 }) {Text('地址:')TextInput({ text: this.persionInfo.address.province }).layoutWeight(1)TextInput({ text: this.persionInfo.address.city }).layoutWeight(1)TextInput({ text: this.persionInfo.address.area }).layoutWeight(1)}.width('100%').padding(20)Row({ space: 20 }) {Button('改变姓名').onClick(() => {this.persionInfo.name = '小程神'})Button('改变省份').onClick(() => {this.persionInfo.address.province = '河北'promptAction.showToast({message: JSON.stringify(this.persionInfo.address)})})}}.width('100%').height('100%')}
}interface Address {province: stringcity: stringarea: string
}interface PersionInfo {name: stringage: stringsex: '男' | '女'address: Address
}
  1. 效果展示

img

  1. 案例分析
  • 在我们修改姓名的时候,姓名也是成功修改,但是我们在修改省份的时候,却没有成功修改,但是数据其实更改的了,但是UI层并没有更新,这就涉及到了鸿蒙里面@State装饰器修饰的引用数据只能修改本身或者第一层数据,而省份是在address里面的第二层,所以自然不会刷新,所以通过修改自身和第一层我们可以更新省份

1.2.2解决方法

  1. 方法一:修改第一层
  • 代码
 Button('改变省份').onClick(() => {this.persionInfo.address = {province:'河北',city:'保定',area:'莲池区'}promptAction.showToast({message: JSON.stringify(this.persionInfo.address)})})
  • 效果展示

img

2.方法二:修改自身

  • 代码演示
     Button('改变省份').onClick(() => {// this.persionInfo.address = {//   province:'河北',//   city:'保定',//   area:'莲池区'// }this.persionInfo={name: '小程',age: '21',sex: '女',address: {province: '河北',city: '黄山市',area: '黄山'}}promptAction.showToast({message: JSON.stringify(this.persionInfo.address)})})
  • 效果展示

img

通过上述方法,我们可以总结为UI更新的原理就是产生了一个新对象,得到一个新对象,UI就会更新,另辟蹊径,我们可以把接口转换为类,然后new一个对象去赋值,然后更新UI

  1. 方法三:new 一个新对象
  • 代码展示
export class AddressModel implements Address {province: string = ''city: string = ''area: string = ''constructor(model: Address) {this.province = model.provincethis.city = model.citythis.area = model.area}
}
export class PersionInfoModel implements PersionInfo {name: string = ''age: string = ''sex: '男' | '女' = '男'address: Address = new AddressModel({} as Address)constructor(model: PersionInfo) {this.name = model.namethis.age = model.agethis.sex = model.sexthis.address = model.address}
}Button('改变省份').onClick(() => {// this.persionInfo.address = {//   province:'河北',//   city:'保定',//   area:'莲池区'// }// this.persionInfo={//   name: '小程',//   age: '21',//   sex: '女',//   address: {//     province: '河北',//     city: '黄山市',//     area: '黄山'//   }//// }this.persionInfo.address.province = '四川'this.persionInfo = new PersionInfoModel(this.persionInfo)promptAction.showToast({message: JSON.stringify(this.persionInfo.address)})
  • 效果展示

img

1.3总结

  1. @State装饰器可以通过数据驱动视图更新
  2. 在鸿蒙中,@State只能监听到引用数据的本身和第一层,不能监听到第二层
  3. 如果想监听到第二层以及第二层往后,可以改变数据的本身、第一层或者new一个新对象

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

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

相关文章

harmony OS NEXTUI开发

UI开发 1. 布局概述 1.1 开发流程1.先确定开发流程 -> 2.分析页面元素构成 ->3.选用合适的布局容器组件1.3 布局元素组成:盒模型2.1 布局分类 2.1 线性布局线性布局是开发中最常用、最基础的布局,通过线性容器Row和Column构建2.1.1 线性布局子元素排列方向:主轴布局子…

harmony OS NEXT组件结构

组件结构 1. 认识基本的组件结构ArkTS通过装饰器@Component 和@Entry 装饰 struct 关键字声明的数据结构,构成一个自定义组件 自定义组件中提供了一个build函数,开发者需要在函数内以链式调用的方式进行基本的UI描述,UI描述的方法请参考UI描述规范srtuct-自定义组件基于stru…

如何使用 vxe-table 来实现高亮行与高亮列,单元格选择高亮移动功能

如何使用 vxe-table 来实现高亮行与高亮列,单元格选择高亮移动功能 查看官网:https://vxetable.cn gitbub:https://github.com/x-extends/vxe-table gitee:https://gitee.com/x-extends/vxe-table 效果代码 通过 rowConfig.isCurrent 启用高亮行功能,columnConfig.isCurre…

Browser-use探索-webui

UI化的Browser-use 拉项目下来:git clone https://github.com/browser-use/web-ui.git # 拉取项目依次安装依赖:# pip install browser-use# playwright install# pip install -r requirements.txt 重新搞个配置文件.env:OPENAI_ENDPOINT=https://api.openai.com/v1 OPENAI_…

Web 页面实现图片放大镜效果

Web 页面实现图片放大镜效果Web 页面实现图片放大镜效果 下面是一个完整的示例代码: <!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>图片放大镜效果</title><style>.container {position: relative;width…

3.A+B 问题三

用while(hasNext())来判断是非还有输入 后面用if判断结束循环的条件 break 结束循环; continue 跳过本次循环 进入下一次循环

save actions 设置

activate save actions on save – 在保存的时候激活save actions optimize imports – 自动删除没有引用的importsreformat file – 自动格式化代码add missing @Override – 在save actions激活的时候直接提添加overrideadd a serialVersionUID – 自动添加序列化id

同源策略SpringBoot允许跨域请求配置

完全允许(测试环境) import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotat…

【Vscode】用Vscode配置简约方便的Qt环境!

其实本文是在好不容易配好的情况下写成 故进食后人 Qt Creator的那个页面真的好丑 写完上学期大作业 这学期还要写的时候终于受不了了 而且各种报错什么的非常不好用 不知道是在干嘛 毕竟谁不想用舒服的字体 然后再配上麻衣学姐的背景和看板娘写代码呢?() 于是我开始探索怎么…

17.6K star!后端接口零代码的神器来了,腾讯开源的ORM库太强了!

"🏆 实时零代码、全功能、强安全 ORM 库 🚀 后端接口和文档零代码,前端定制返回 JSON 的数据和结构"嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法"🏆 实时零代码、全功能、强安全 ORM 库 🚀 后端接口和文…

WPF 和 Avalonia 开发者的 html css 前端指南 WrapPanel 篇

本文主要是向大家列出 WPF 和 Avalonia 的 WrapPanel 在 html 和 css 的实现方法。WPF 和 Avalonia 开发者的 html css 前端指南 WrapPanel 篇笔者前端框架使用的是 Vue3 + Deno。 笔者主要会以 Avalonia 作为 C# 技术部分的示例。 本文主要是向大家列出 WPF 和 Avalonia 的 Wr…

os管理文件和open创建文件

目录os基础操作获取当前工作目录更改工作目录列出目录内容创建目录删除目录、文件文件重命名路径拼接与拆分判断路径是否存在递归遍历目录open创建文件读取模式下写入模式下 os基础操作 获取当前工作目录 import os #返回的是一个绝对路径 print(f"当前的工作目录为:{os.…