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

ArkUI -- 状态管理的更新机制

状态管理 V1 和 V2 触发 UI 更新

状态管理 V1 使用代理观察数据,创建状态变量时,会同时创建一个代理观察者,该观察者可以感知代理变化,但无法精准观测到实际数据变化。

状态管理 V2 增强了数据的观察能力,使数据本身可观察,更新数据时,会触发相应视图的更新。

特性状态管理 V1状态管理 V2
独立于 UI状态变量不能独立于 UI状态变量独立于 UI,更新数据会触发相应视图的更新
深度观测无法深度观测和深度监听,只能感知对象属性第一层的变化支持对象的深度观测和深度监听,且不影响观测性能
精准更新更新对象中属性时,存在冗余更新的问题支持对象中属性级精准更新
易用性装饰器间配合使用限制多,不易用,不利于组件化装饰器易用性高、拓展性强,有利于组件化

状态管理的更新机制

状态管理原理介绍

状态管理的核心逻辑是处理状态变量、自定义组件和系统组件之间的绑定关系。

状态管理循环执行两大步骤:收集依赖和触发更新

  • 收集与状态变量绑定的组件标识
  • 当状态变量发生变化时,对收集的组件执行标 “脏”,刷新对应的 UI,同时更新依赖观察

状态管理的基本流程如图:

收集依赖

收集依赖是指建立状态变量与组件之间的数据绑定关系。

一个 UI 界面可能使用了多个状态变量,在修改状态变量时,仅与其相关的组件进行 UI 刷新,其他不相关的组件不会刷新。因此,UI 的刷新需要明确哪些组件使用了被修改的状态变量,以实现这些组件的精准刷新。

每个状态变量中都维护了一个 Set 集合,保存所有与其绑定的组件的标识信息 (系统组件的唯一标识 elementId),即框架收集依赖的过程

【示例】

@Entry@Componentstruct Index{@Stateage:number=10;@Stategrade:number=5;build(){Column(){Text('age is: '+this.age)// Text1Text('grade is: '+this.grade)// Text1Button('change age')// Button1.onClick(()=>{this.age++;})Button('change grade')// Button2.onClick(()=>{this.grade++;})}}}

上述示例,Index 中定义了两个状态变量 age 和 grade,框架收集依赖的步骤为:

  • 调用 build 方法,创建自定义组件 Index
  • 执行到Text('age is: ' + this.age)时,为了显示文本内容,需要读取 this.age 的值 (Text2 同理)
  • age 和 grade 都是 @State 装饰的状态变量,其在被读取时会收集当前正在渲染的系统组件的唯一标识 elementId,并将其存储到状态变量维护的 Set 集合中

触发更新

当状态变量发生改变时,状态管理框架会通知所有依赖于它的 UI 组件,重新计算并刷新,此过程称为触发更新。

触发更新可分为三个步骤:

  • 计算状态变量发生改变后的新值
  • 修改状态变量的值,并将与其绑定的组件标脏
  • 刷新所有标脏的节点,更新 UI 的同时重新收集依赖

更新是以自定义组件为单位的,每个自定义组件中维护了一个标脏的系统组件集合,用于保存在当前 UI 更新周期中标脏的系统组件的 elementId,即需要刷新的组件标识

触发更新就是,当状态变量发生改变时,将其收集到的依赖组件,标记为“脏”,在下一个 UI 更新周期中,只刷新标脏的组件,实现最小化更新。

同样对上述示例代码,点击 Button 组件修改状态变量,对应的 Text 组件刷新,具体步骤为:

  • 在点击事件中处理this.age++,由于 age 是状态变量,在改值的过程中会执行状态管理内部的更新操作
  • 在状态变量 age 的更新操作中,将其依赖集合中系统组件的 elementId 加入到其所属自定义组件 Index 的脏系统组件集合中 (每个自定义组件中维护了一个标脏的系统组件集合,用于保存在当前 UI 更新周期中标脏的系统组件的 elementId)
  • 完成系统组件标脏后,将状态变量 age 所属的自定义组件 Index 标脏,加入到标脏的自定义组件节点列表中 (脏自定义组件列表),并请求一个刷新信号 (Vsync 信号)
  • 在下一个 UI 更新周期中 (下一个帧信号),框架遍历脏自定义组件列表,重新调用其rerender方法 (rerender 方法是由系统生成的),遍历自定义组件 Index 中的脏系统组件,刷新 Text 组件并更新依赖

状态管理 V1 和 V2 的更新机制差异

相比于 V1 状态管理,状态管理 V2 在状态变量变化时,会异步标脏组件,如下图:

V1组件的更新
  • 步骤1:事件触发修改 V1 状态变量,观察状态变量的变化
  • 步骤2:执行 @Watch 回调
  • 步骤3:执行节点标脏,将脏节点放在脏节点列表中,并请求Vsync信号
  • 步骤4:更新脏节点列表,先更新父组件,再更新子组件
  • 步骤5:若状态变量再次发生变化,会执行步骤4,步骤4在一个 Vsync 周期内的迭代不会超过 3 次,第 3 次迭代后,标脏的节点只会加到脏节点列表,等下一个 Vsync 进行脏节点更新
V2组件的更新

V2 状态管理相比 V1,新增异步执行 @Computed,@Monitor 和 节点标脏

  • 步骤1:事件触发修改 V2 状态变量,抛Promise异步任务
  • 步骤2:等待事件的逻辑处理完成后 (如 onClick 事件),执行步骤1抛出的 Promise 回调
  • 步骤3:执行 @Computed 变量更新
  • 步骤4:若 @Computed 回调中有状态变量的变化,回到步骤3,否则进入步骤5
  • 步骤5:执行 @Monitor 回调函数
  • 步骤6:若 @Monitor 回调中有状态变量的变化,则进入步骤3,否则进入步骤7
  • 步骤7:执行节点标脏,将脏节点放在脏节点列表中,并请求Vsync信号
  • 步骤8:更新脏节点列表,先更新父组件,再更新子组件 (同 V1 组件的更新,一个 Vsync 周期内迭代不会超过 3 次)
  • V1 状态变量的变化,会触发 @Watch 的同步执行,若状态变量被修改多次,则 @Watch 回调会同步执行多次
  • V2 状态变量的变化,会触发 @Monitor 的异步执行,若在一次事件中状态变量被多次修改,@Monitor 回调只会执行一次
http://www.cnnetsun.cn/news/2623423.html

相关文章:

  • DistroAV完整指南:如何通过NDI技术实现OBS Studio网络视频传输
  • 三步解锁:Mac用户如何零成本解决跨平台局域网通信难题
  • AI写论文哪个好用?2026年5款AI写论文工具指南,避开知网查重常见问题!
  • Gemini流式响应在Go中的零拷贝处理术:降低GC压力68%,吞吐提升2.3倍
  • Claude长文本处理卡顿诊断指南(含火焰图分析+KV Cache内存泄漏定位工具链)
  • 如何使用Legacy iOS Kit实现旧款iOS设备降级与越狱的完整指南
  • AbMole丨Rocaglamide:一种能调控翻译起始与细胞应激反应的天然产物
  • 第十三周学习
  • Rio框架:用纯 Python 搞定前后端,构建现代化 Web 与桌面应用
  • 深度解析MKL24Z32VLH4:64引脚Kinetis KL2系列ARM Cortex-M0+超低功耗MCU
  • Pythonclassmethod与staticmethod深究
  • 旧电脑电源改造DIY实验电源:低成本实现多路可调稳压输出
  • 企业内网应用通过Taotoken代理安全稳定地调用外部大模型API
  • 如何通过curl命令快速测试Taotoken多模型API的连通性与响应
  • 对比直接调用与通过聚合平台调用,网站AI服务延迟稳定性感受
  • C++ 继承机制详解下:多继承、虚继承与菱形继承底层原理
  • Honey Select 2终极补丁:如何5分钟完成游戏体验全面升级
  • R语言gtsummary包保姆级教程:从临床数据到发表级三线表,一篇搞定
  • 别再被K线骗了!Python量化实现筹码峰战法
  • Claude + LangChain集成测试失效真相:Token截断、上下文漂移与状态同步漏洞(附可复用的断言校验DSL)
  • 基于Arduino的智能温控风扇系统:从传感器到PWM调速的嵌入式实践
  • 私有化大模型选型必看:DeepSeek企业版vs Llama3-70B商用版,9项关键指标横向对比
  • Beyond Compare 5 终极密钥生成器:开源高效的完整激活解决方案
  • 工程避坑:长上下文导致成本爆炸的 7 种控制手段
  • 基于Arduino与压电传感器的DIY防盗报警器制作全攻略
  • 【ACM出版、西南交通大学主办、启动评优】第二届具身智能与大模型国际学术会议(EILM 2026)
  • Windows 11系统下,用EVE-NG模拟器搭建你的第一个企业级网络实验环境(从下载到拓扑测试)
  • 如何用SysML v2构建下一代系统模型:从概念到实现的完整指南
  • 从桌面快捷方式到系统自动化:手把手教你用WshShell对象玩转Windows脚本
  • 从游戏开发到机器人集群:Boids算法在Unity3D和ROS中的跨界应用指南