鸿蒙中级课程笔记2—状态管理V2—@Local

@Local装饰器:组件内部状态

为了实现对@ComponentV2装饰的自定义组件中变量变化的观测,开发者可以使用@Local装饰器装饰变量。

在阅读本文档前,建议提前阅读:@ComponentV2。常见问题请参考组件内状态变量常见问题。

说明

从API version 12开始,在@ComponentV2装饰的自定义组件中支持使用@Local装饰器。

从API version 12开始,该装饰器支持在元服务中使用。

概述

@Local表示组件内部的状态,使得自定义组件内部的变量具有观察变化的能力:

  • 被@Local装饰的变量无法从外部初始化,因此必须在组件内部进行初始化。

  • 当被@Local装饰的变量变化时,会刷新使用该变量的组件。

  • @Local支持观测number、boolean、string、Object、class等基本类型以及Array、Set、Map、Date等内嵌类型。

  • @Local的观测能力仅限于被装饰的变量本身。当装饰简单类型时,能够观测到对变量的赋值;当装饰对象类型时,仅能观测到对对象整体的赋值;当装饰数组类型时,能观测到数组整体以及数组元素项的变化;当装饰Array、Set、Map、Date等内嵌类型时,可以观测到通过API调用带来的变化。详见观察变化。

  • @Local支持null、undefined以及联合类型。

状态管理V1版本@State装饰器的局限性

状态管理V1使用@State装饰器定义组件中的基础状态变量,该状态变量常用来作为组件内部状态,在组件内使用。但由于@State装饰器又能够从外部初始化,因此无法确保@State装饰变量的初始值一定为组件内部定义的值。

class ComponentInfo { public name: string; public count: number; public message: string; constructor(name: string, count: number, message: string) { this.name = name; this.count = count; this.message = message; } } @Component struct Child { @State componentInfo: ComponentInfo = new ComponentInfo('Child', 1, 'Hello World'); // 父组件传递的componentInfo会覆盖初始值 build() { Column() { Text(`componentInfo.message is ${this.componentInfo.message}`) } } } @Entry @Component struct Index { build() { Column() { Child({ componentInfo: new ComponentInfo('Unknown', 0, 'Error') }) } } }

上述代码中,可以通过在初始化Child自定义组件时传入新的值来覆盖作为内部状态变量使用的componentInfo。但Child自定义组件并不能感知到componentInfo从外部进行了初始化,这不利于自定义组件内部状态的管理。因此推出@Local装饰器表示组件的内部状态。

@Local装饰器说明

@Local变量装饰器说明
装饰器参数无。
可装饰的变量类型Object、class、string、number、boolean、enum等基本类型以及Array、Date、Map、Set等内嵌类型。支持null、undefined以及联合类型。
装饰变量的初始值必须本地初始化,不允许外部传入初始化。

@Local装饰变量传递

传递规则说明
从父组件初始化@Local装饰的变量仅允许本地初始化,无法从外部传入初始化。
初始化子组件@Local装饰的变量可以初始化子组件中@Param装饰的变量。

观察@Local装饰变量变化

使用@Local装饰的变量具有观察变化的能力。当装饰的变量发生变化时,会触发该变量绑定的UI组件刷新

  • 当装饰的变量类型为boolean、string、number时,可以观察到对变量赋值的变化

  • @Local装饰的变量类型为null、undefined以及联合类型,变量类型改变后,UI会随之刷新。如count类型为number | undefined,初始count值为number类型,将count值变为undefined类型,UI会随之刷新。

  • 当装饰的变量类型为类对象时,仅可以观察到对类对象整体赋值的变化,无法直接观察到对类成员属性赋值的变化,对类成员属性的观察依赖@ObservedV2和@Trace装饰器。注意,API version 19之前,@Local无法和@Observed装饰的类实例对象混用。API version 19及以后,支持部分状态管理V1V2混用能力,允许@Local和@Observed同时使用,详情见状态管理V1V2混用文档。

    class RawObject { public name: string; constructor(name: string) { this.name = name; } } @ObservedV2 class ObservedObject { @Trace public name: string; constructor(name: string) { this.name = name; } } @Entry @ComponentV2 struct Index { @Local rawObject: RawObject = new RawObject('rawObject'); @Local observedObject: ObservedObject = new ObservedObject('observedObject'); build() { Column() { Text(`${this.rawObject.name}`) Text(`${this.observedObject.name}`) Button('change object') .onClick(() => { // 对类对象整体的修改均能观察到 this.rawObject = new RawObject('new rawObject'); this.observedObject = new ObservedObject('new observedObject'); }) Button('change name') .onClick(() => { // @Local不具备观察类对象属性的能力,因此对rawObject.name的修改无法观察到 this.rawObject.name = 'new rawObject name'; // 由于ObservedObject的name属性被@Trace装饰,因此对observedObject.name的修改能被观察到 this.observedObject.name = 'new observedObject name'; }) } } }
  • 当装饰简单类型数组时,可以观察到数组整体或数组项的变化

  • 当装饰的变量是嵌套类或对象数组时,@Local无法观察深层对象属性的变化。对深层对象属性的观测依赖@ObservedV2与@Trace装饰器。

  • 当装饰内置类型时,可以观察到变量整体赋值及API调用带来的变化

    类型可观察变化的API
    Arraypush, pop, shift, unshift, splice, copyWithin, fill, reverse, sort
    DatesetFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime, setUTCFullYear, setUTCMonth, setUTCDate, setUTCHours, setUTCMinutes, setUTCSeconds, setUTCMilliseconds
    Mapset, clear, delete
    Setadd, clear, delete

@Local使用限制

@Local装饰器存在以下使用限制:

  • @Local装饰器只能在@ComponentV2装饰的自定义组件中使用,否则编译时报错。

  • @Local装饰的变量表示组件内部状态,不允许从外部传入初始化,否则编译时报错。

@Local与@State对比

@Local与@State的用法、功能对比如下:

用法@State@Local
参数无。无。
从父组件初始化可选。不允许外部初始化。
观察能力能观测变量本身以及一层的成员属性,无法深度观测能观测变量本身,深度观测依赖@Trace装饰器。
数据传递可以作为数据源和子组件中状态变量同步。可以作为数据源和子组件中状态变量同步。

使用场景

观测对象整体变化

被@ObservedV2与@Trace装饰的类对象实例,具有深度观测对象属性的能力。使用@Local装饰对象,可以达到观测对象本身变化的效果。例子参考华为中级课程——@Local——观测对象整体变化

装饰Array类型变量

当装饰的对象是Array时,可以观察到Array整体的赋值,同时可以通过调用Array的接口push, pop, shift, unshift, splice, copyWithin, fill, reverse, sort更新Array中的数据。同时,数组中某个元素的直接赋值也可以监测到。华为中级课程——@Local——装饰Array类型变量

装饰Date类型变量

当装饰的对象是Date时,可以观察到Date整体的赋值,同时可通过调用Date的接口setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime, setUTCFullYear, setUTCMonth, setUTCDate, setUTCHours, setUTCMinutes, setUTCSeconds, setUTCMilliseconds更新Date的属性。华为中级课程——@Local——装饰Date类型变量

装饰Map类型变量

当装饰的对象是Map时,可以观察到对Map整体的赋值,同时可以通过调用Map的接口set, clear, delete更新Map中的数据。华为中级课程——@Local——装饰Map类型变量

装饰Set类型变量

当装饰的对象是Set时,可以观察到对Set整体的赋值,同时可以通过调用Set的接口add, clear, delete更新Set中的数据。华为中级课程——@Local——装饰Set类型变量

联合类型

@Local支持null、undefined以及联合类型。在下面的示例中,count类型为number | undefined,初始count值为number类型,将count值变为undefined类型,UI会随之刷新。华为中级课程——@Local——联合类型

常见问题

在状态管理V2中使用animateTo动画效果异常

animateTo暂不支持直接在状态管理V2中动画前改变值。

@Entry @ComponentV2 struct Index { @Local w: number = 50; // 宽度 @Local h: number = 50; // 高度 @Local message: string = 'Hello'; build() { Column() { Button('change size') .margin(20) .onClick(() => { // 在执行动画前,存在额外的修改 this.w = 100; this.h = 100; this.message = 'Hello World'; this.getUIContext().animateTo({ duration: 1000 }, () => { this.w = 200; this.h = 200; this.message = 'Hello ArkUI'; }) }) Column() { Text(`${this.message}`) } .backgroundColor('#ff17a98d') .width(this.w) .height(this.h) } } }

上述代码中,开发者预期的动画效果是:绿色矩形从长宽100变为200,字符串从Hello World变为Hello ArkUI。但由于当前animateTo与V2的刷新机制不兼容,执行动画前的额外修改未生效,实际显示的动画效果是:绿色矩形从长宽50变为200,字符串从Hello变为Hello ArkUI。

API version 22开始,可以使用applySync接口实现预期的显示效果。

import { UIUtils } from '@kit.ArkUI'; @Entry @ComponentV2 struct Index { @Local w: number = 50; // 宽度 @Local h: number = 50; // 高度 @Local message: string = 'Hello'; build() { Column() { Button('change size') .margin(20) .onClick(() => { // 在执行动画前,存在额外的修改 UIUtils.applySync(() => { this.w = 100; this.h = 100; this.message = 'Hello World'; }) this.getUIContext().animateTo({ duration: 1000 }, () => { this.w = 200; this.h = 200; this.message = 'Hello ArkUI'; }) }) Column() { Text(`${this.message}`) } .backgroundColor('#ff17a98d') .width(this.w) .height(this.h) } } }

原理为使用applySync接口同步刷新闭包函数内的状态变量变化,再执行原来的动画达成预期的效果。

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

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

相关文章

鸿蒙中级课程笔记2—状态管理V2—@Param

为了增强子组件接受外部参数输入的能力,开发者可以使用Param装饰器。 Param不仅可以接受组件外部输入,还可以接受Local的同步变化。在阅读本文档前,建议提前阅读:Local。 说明 从API version 12开始,在ComponentV2装…

鸿蒙中级课程笔记2—状态管理V2—@Once、@Event

Once:初始化同步一次 想要实现仅从外部初始化一次且不接受后续同步变化的能力,可以使用Once装饰器搭配Param装饰器。 阅读本文档前,请先阅读Param。 说明 从API version 12开始,在ComponentV2装饰的自定义组件中支持使用Once装…

2026广安种植牙优质机构推荐榜 高性价比之选

2026广安种植牙优质机构推荐榜 高性价比之选一、行业背景与评测依据据《2026中国口腔医疗行业发展白皮书》数据显示,我国45岁以上人群缺牙率达63.2%,65岁以上人群全口缺牙率超10%,口腔修复需求呈逐年攀升态势。 川东…

深入 Pinia 工作原理:响应式核心、持久化机制与缓存策略 - 教程

深入 Pinia 工作原理:响应式核心、持久化机制与缓存策略 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "C…

构建AI Agent的自适应学习系统

构建AI Agent的自适应学习系统 关键词:AI Agent、自适应学习系统、机器学习、强化学习、神经网络 摘要:本文旨在深入探讨构建AI Agent的自适应学习系统这一前沿技术领域。通过详细阐述自适应学习系统的核心概念、算法原理、数学模型,结合项目实战案例,展示如何实现一个高效…

软件测试之单元测试

所谓单元测试指,指的是对软件中最小可测试单元开展细致的检查与验证工作。 具体而言,它主要用于检验单个类的准确性,确保其功能符合预期。 单元测试与集成测试、系统测试存在显著差异。它是软件开发流程中前置的测试环节,规模最…

京城爱加陪诊官方电话声明

为保障广大客户的合法权益,杜绝虚假信息误导,现就京城爱加陪诊(以下简称“我方”)官方联系电话事宜郑重声明如下: 我方唯一官方咨询及服务预约电话为:010-53656582。该电话为客户对接陪诊咨询、需求登记、服务沟…

如何高效阅读学术文献:硕士研究生完全指南

如何高效阅读学术文献:硕士研究生完全指南Posted on 2026-01-24 20:05 steve.z 阅读(0) 评论(0) 收藏 举报如何高效阅读学术文献:硕士研究生完全指南"What I cannot create, I do not understand." —…

windows版中间件启动 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

实用指南:我在CSDN学MYSQL之----数据库基本概念和基本知识(上)

实用指南:我在CSDN学MYSQL之----数据库基本概念和基本知识(上)2026-01-24 20:04 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !im…

从0到1!AI提示工程架构师助力智能营销腾飞

从0到1!AI提示工程架构师助力智能营销腾飞 一、当智能营销遇上“卡脖子”:我们需要什么样的AI桥梁? 凌晨3点,某美妆品牌的营销总监盯着电脑屏幕上的12% email打开率发愁——这是第8次调整文案了,可用户依然对千篇一律…

华为MetaERP实现智能高效排产的核心是通过人工智能、大数据、数字孪生等技术与传统ERP生产计划模块深度融合,构建动态优化、实时响应的排产体系

华为MetaERP实现智能高效排产的核心是通过人工智能、大数据、数字孪生等技术与传统ERP生产计划模块深度融合,构建动态优化、实时响应的排产体系。以下是其关键实现路径:1. 基于AI的智能排产引擎多目标优化算法:综合考虑订单交期、产能利用率、…

一文读懂AI产品经理:职责、技能与学习路径全攻略,如何成为AI产品经理?

本文详细介绍了AI产品经理的定义、职责、类型及与传统互联网产品经理的区别,强调技术理解能力成为AI产品经理的核心门槛。文章分析了AI产品经理必备的算法理解、系统架构、数据分析和业务转化等能力,并为在校生和传统产品经理提供了转型路径。最后提供了…

收藏级干货:DeepSeek Engram架构解析:大模型语言理解的新思路

DeepSeek与北大联合发布Engram架构,将语言理解分为"推理"和"知识"两部分。通过2-Grams/3-Grams分词和Multi-Head Hash存储短语,结合Context-aware Gating机制解决多义词问题。Engram将传统模型中用于"组合固定短语"的大量…

知识图谱如何提升大模型性能?WeKnora实现原理与代码解析

WeKnora通过知识图谱增强大模型检索能力,采用LLM驱动实体和关系抽取,构建文档块关系网络。系统支持并发处理,使用PMIStrength混合算法计算关系权重,实现直接关联和间接关联查询,并提供可视化展示。这一GraphRAG方案解决…

大模型训练项目如何落地:完整流程与实战技巧

本文详解大模型训练三阶段(预训练、SFT微调、强化学习)及AI训练师工作。重点讲解项目落地流程:需求承接、标注规则制定(安全性、指令遵循、准确性等维度)、数据筛选与标注管理、质量控制与迭代。以SFT项目为例&#xf…

AI产品经理vs传统产品经理:大模型时代必备技能与学习路线

本文详细介绍了AI产品经理与传统产品经理的区别,强调"懂技术"是AI产品经理的必要条件。文章阐述了AI产品经理的职责、类型(软件/硬件产品经理)、必备技能(技术能力、数据分析、业务sense)以及成为路径。最后…

DeepSeek MODEL1架构级跃迁:从Transformer到状态空间模型的革命性突破

DeepSeek推出的MODEL1项目代表了一次大模型架构的跃迁,而非简单版本升级。它摒弃了Transformer架构,转向融合状态空间模型(SSM)与强化学习推理单元的新范式,引入可微分状态记忆体和递归推理单元,支持长程规划和动态状态追踪。若成…

大模型新架构STEM:静态稀疏化提升效率与稳定性,代码示例全解析【收藏必看】

STEM是由CMU与Meta开发的新型大模型稀疏架构,将FFN层的上投影矩阵替换为基于token ID的静态查找表,避免了MoE的动态路由问题。这种方法提升了计算效率(减少1/3计算量)、训练稳定性和知识可编辑性,同时具备"测试时容量扩展"特性&…

LLM微调实战教程:从零开始使用LLaMA Factory打造专业大模型,附完整代码+部署指南

本文系统介绍LLM微调技术,特别是指令监督微调(SFT)方法。以LLaMA Factory为工具,详细演示从数据准备、格式化,到全量微调(Full FT)和参数高效微调(PEFT/LoRA)训练,最后通过API部署上线的完整流程。提供详细配置示例和代码片段&…