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

深入解析鸿蒙 ArkTS 中的 @Local 装饰器

目录

前言

1.什么是@Local

2.@Local的特点与优势

1.私有状态

2.响应式

3.与V2生命周期兼容

4.类型安全

3.详细用法

1. boolean、string、number

2. 类对象

3.单类型数组

4.嵌套类或对象数组

5.内置类型


前言

        在鸿蒙 ArkTS 开发中,组件的状态管理是核心能力之一。随着 ArkTS 0.8+ 版本的演进,V2 组件体系引入了新的状态管理装饰器,其中 @Local 是最常用的一种。本文将全面介绍 @Local 的作用、使用方法、优势及实际案例。

        这里需要说明的是:

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

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

1.什么是@Local

        @Local 是 ArkTS V2 组件体系中用于声明组件内部私有状态的装饰器。它类似于V1的 @State,但在V2中功能更精细,性能更高。@Local 声明的状态只属于当前组件,外部无法直接访问或修改,保证了组件内部状态的封装性和独立性。 

        使用@Local 非常简单,你只需要在组件的类成员上加上装饰器即可:

@ComponentV2
struct CounterComponent {@Local count: number = 0; // 内部状态build() {Column() {Text(`当前计数:${this.count}`).fontSize(24).padding(20)Row() {Button('增加').onClick(() => { this.count++ })Button('减少').onClick(() => { this.count-- })}.justifyContent(FlexAlign.SpaceAround)}}
}

        在上面的代码中:

        @Local count: number = 0:定义组件的私有状态count,初始值为0。

        当count 发生变化时,组件会自动重新渲染。

        外部无法直接访问 count,保证状态的封装性。

2.@Local的特点与优势

1.私有状态

        @Local声明的状态仅属于当前组件,保证了组件内部的状态封装。其他组件或父组件无法直接访问或修改它。

2.响应式

        组件会自动监听@Local 修饰的状态,当状态发生变化时,组件会触发重新渲染,无需手动刷新。

3.与V2生命周期兼容

        @Local与V2组件的生命周期和性能优化机制兼容,支持冻结非活跃组件的状态监听,提高性能。

4.类型安全

        使用TypeScript 的类型系统,@Local 支持类型推导和静态检查,减少运行时错误。

3.详细用法

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

1. boolean、string、number

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

@ComponentV2
struct TodoListComponent {@Local todos: string[] = []addTodo(todo: string) {this.todos = [...this.todos, todo]; // 替换式赋值,触发渲染}build() {Column() {ForEach(this.todos, (item, index) => {ListItem() {Text(item)}}, item => item)Button('添加任务').onClick(() => this.addTodo('新任务'))}}
}

2. 类对象

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

        如果我们定义了一个RawObject对象:

class RawObject {name: string;constructor(name: string) {this.name = name;}
}
@ObservedV2
class ObservedObject {@Trace name: string;constructor(name: string) {this.name = name;}
}@Entry
@ComponentV2
struct LocalExample01 {@Local rawObject: RawObject = new RawObject("rawObject");@Local observedObject: ObservedObject = new ObservedObject("observedObject");build() {NavDestination(){Column() {Row(){Column(){Text(`${this.rawObject.name}`).margin({top:20})Text(`${this.observedObject.name}`).margin({top:20})Button("change object").onClick(() => {// 对类对象整体的修改均能观察到this.rawObject = new RawObject("new rawObject");this.observedObject = new ObservedObject("new observedObject");}).margin({top:20})Button("change name").onClick(() => {// @Local不具备观察类对象属性的能力,因此对rawObject.name的修改无法观察到this.rawObject.name = "new rawObject name";// 由于ObservedObject的name属性被@Trace装饰,因此对observedObject.name的修改能被观察到this.observedObject.name = "new observedObject name";}).margin({top:20})}.backgroundColor(Color.White).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).margin({top:20,bottom:20})}.margin({top:20,left:20,right:20}).borderColor(Color.Gray).width('100%').borderRadius(5).backgroundColor(Color.White).justifyContent(FlexAlign.Center)}.padding({left: '12vp',right: '12vp',bottom: '24vp'}).backgroundColor('#F1F3F5').width('100%').height('100%')}.title("Local修饰类对象")}
}

3.单类型数组

        当装饰简单类型数组时,可以观察到数组整体或数组项的变化。

        以下面的代码为例,点击按钮之后,UI中始终数组元素的Text实时刷新。

@Entry
@ComponentV2
struct LocalExample02 {@Local numArr: number[] = [1,2,3,4,5];  // 使用@Local装饰一维数组变量@Local dimensionTwo: number[][] = [[1,2,3],[4,5,6]]; // 使用@Local装饰二维数组变量build() {NavDestination(){Column() {Text(`${this.numArr[0]}`)Text(`${this.numArr[1]}`)Text(`${this.numArr[2]}`)Text(`${this.dimensionTwo[0][0]}`)Text(`${this.dimensionTwo[1][1]}`)Button("change array item") // 按钮1:修改数组中的特定元素.onClick(() => {this.numArr[0]++;this.numArr[1] += 2;this.dimensionTwo[0][0] = 0;this.dimensionTwo[1][1] = 0;})Button("change whole array") // 按钮2:替换整个数组.onClick(() => {this.numArr = [5,4,3,2,1];this.dimensionTwo = [[7,8,9],[0,1,2]];})}.justifyContent(FlexAlign.SpaceEvenly).width('100%').height('100%')}.title("简单的数组")}
}

4.嵌套类或对象数组

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

5.内置类型

        当装饰内置类型时,可以观察到变量整体赋值及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
http://www.xdnf.cn/news/18361.html

相关文章:

  • 【解决办法】wps的word文档编辑时字体的下方出现灰色的底色如何删除
  • CAM可视化卷积神经网络
  • 深度学习:入门简介
  • AI推理革命:从Sequential Thinking到Agentic AI的演进之路——揭秘大语言模型思维进化的四重奏
  • 上海人工智能实验室开源基于Intern-S1同等技术的轻量化开源多模态推理模型
  • logback-spring.xml 文件
  • 车载 GPS 与手机导航的终极对决:谁在复杂路况下更胜一筹?
  • UE5 将纯蓝图项目转为 C++ 项目
  • MongoDB 完整指南
  • 安全运维过程文档体系规范
  • 如何轻松永久删除 Android 手机上的短信
  • Android音频学习(十四)——加载音频设备
  • 什么是Jmeter?Jmeter使用的原理步骤是什么?
  • day38-HTTP
  • 第41周——人脸图像生成
  • 携程旅游的 AI 网关落地实践
  • 计算机网络技术-第七章
  • Ingress控制器深度解析:Nginx与Traefik实战指南
  • Java的运行时数据区
  • ICMP 协议分析
  • 从零到一:RAGFlow 本地部署全攻略
  • JeeSite V5.13.0 发布,升级 Spring Boot 3.5,Cloud 2025,AI 1.0,Vite 7
  • 数据结构-HashMap
  • Vue2+Vue3前端开发_Day5
  • 【neo4j】安装使用教程
  • lesson44:Redis 数据库全解析:从数据类型到高级应用
  • 计算机网络:网络基础、TCP编程
  • 如何自定义一个SpringBoot Starter
  • 密码管理中明文密码与空密码的危害与预防
  • 继承(Inheritance)