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

HarmonyOS:@State、@Prop、@Link

一、@State装饰器

@State装饰器:组件内状态
@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就可以触发其直接绑定UI组件的刷新。当状态改变时,UI会发生对应的渲染改变。

在状态变量相关装饰器中,@State是最基础的,使变量拥有状态属性的装饰器,它也是大部分状态变量的数据源。

说明
从API version 9开始,该装饰器支持在ArkTS卡片中使用。
从API version 11开始,该装饰器支持在元服务中使用。

1.1 概述

@State装饰的变量,与声明式范式中的其他被装饰变量一样,是私有的,只能从组件内部访问,在声明时必须指定其类型和本地初始化。初始化也可选择使用命名参数机制从父组件完成初始化。

@State装饰的变量拥有以下特点:

  • @State装饰的变量与子组件中的@Prop装饰变量之间建立单向数据同步,与@Link、@ObjectLink装饰变量之间建立双向数据同步。
  • @State装饰的变量生命周期与其所属自定义组件的生命周期相同。
1.2 装饰器使用规则说明
@State变量装饰器说明
装饰器参数
同步类型不与父组件中任何类型的变量同步。
允许装饰的变量类型Object、class、string、number、boolean、enum类型,以及这些类型的数组。
支持Date类型。API11及以上支持Map、Set类型。
支持undefined和null类型。
支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。
类型必须被指定。
支持类型的场景请参考观察变化。
不支持any。
API11及以上支持上述支持类型的联合类型,比如string | number, string | undefined 或者 ClassA | null,示例见@State支持联合类型实例。
注意
当使用undefined和null的时候,建议显式指定类型,遵循TypeScript类型校验,比如:@State a : string | undefined = undefined是推荐的,不推荐@State a: string = undefined。
被装饰变量的初始值必须本地初始化。
1.3 变量的传递/访问规则说明
传递/访问说明
从父组件初始化可选,从父组件初始化或者本地初始化。如果从父组件初始化将会覆盖本地初始化。支持父组件中常规变量(常规变量对@State赋值,只是数值的初始化,常规变量的变化不会触发UI刷新,只有状态变量才能触发UI刷新)、@State、@Link、@Prop、@Provide、@Consume、@ObjectLink、@StorageLink、@StorageProp、@LocalStorageLink和@LocalStorageProp装饰的变量,初始化子组件的@State。
用于初始化子组件@State装饰的变量支持初始化子组件的常规变量、@State、@Link、@Prop、@Provide。
是否支持组件外访问不支持,只能在组件内访问。

初始化规则图示
在这里插入图片描述

1.4 观察变化和行为表现

并不是状态变量的所有更改都会引起UI的刷新,只有可以被框架观察到的修改才会引起UI刷新。

二、@Prop装饰器

@Prop装饰器:父子单向同步
@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

说明
从API version 9开始,该装饰器支持在ArkTS卡片中使用。
从API version 11开始,该装饰器支持在元服务中使用。

2.1 概述

@Prop装饰的变量和父组件建立单向的同步关系:

  • @Prop变量允许在本地修改,但修改后的变化不会同步回父组件。
  • 当数据源更改时,@Prop装饰的变量都会更新,并且会覆盖本地所有更改。因此,数值的同步是父组件到子组件(所属组件),子组件数值的变化不会同步到父组件。
2.2 限制条件
  • @Prop装饰变量时会进行深拷贝,在拷贝的过程中除了基本类型、Map、Set、Date、Array外,都会丢失类型。例如PixelMap等通过NAPI提供的复杂类型,由于有部分实现在Native侧,因此无法在ArkTS侧通过深拷贝获得完整的数据。
  • @Prop装饰器不能在@Entry装饰的自定义组件中使用。
2.3 装饰器使用规则说明
@Prop变量装饰器说明
装饰器参数
同步类型单向同步:对父组件状态变量值的修改,将同步给子组件@Prop装饰的变量,子组件@Prop变量的修改不会同步到父组件的状态变量上。嵌套类型的场景请参考观察变化。
允许装饰的变量类型Object、class、string、number、boolean、enum类型,以及这些类型的数组。
不支持any,支持undefined和null。
支持Date类型。
API11及以上支持Map、Set类型。
支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。
必须指定类型。
@Prop和数据源类型需要相同,有以下三种情况:
- @Prop装饰的变量和@State以及其他装饰器同步时双方的类型必须相同,示例请参考父组件@State到子组件@Prop简单数据类型同步。
- @Prop装饰的变量和@State以及其他装饰器装饰的数组的项同步时 ,@Prop的类型需要和@State装饰的数组的数组项相同,比如@Prop : T和@State : Array,示例请参考父组件@State数组中的项到子组件@Prop简单数据类型同步。
- 当父组件状态变量为Object或者class时,@Prop装饰的变量和父组件状态变量的属性类型相同,示例请参考从父组件中的@State类对象属性到@Prop简单类型的同步。
支持类型的场景请参考观察变化
API11及以上支持上述支持类型的联合类型,
比如string | number, string | undefined 或者 ClassA | null,示例见Prop支持联合类型实例。
注意
当使用undefined和null的时候,建议显式指定类型,遵循TypeScript类型校验,比如:@Prop a : string
嵌套传递层数在组件复用场景,建议@Prop深度嵌套数据不要超过5层,嵌套太多会导致深拷贝占用的空间过大以及GarbageCollection(垃圾回收),引起性能问题,此时更建议使用@ObjectLink。
被装饰变量的初始值允许本地初始化。如果在API 11中和@Require结合使用,则必须父组件构造传参。
2.4 变量的传递/访问规则说明
传递/访问说明
从父组件初始化如果本地有初始化,则是可选的。没有的话,则必选,支持父组件中的常规变量(常规变量对@Prop赋值,只是数值的初始化,常规变量的变化不会触发UI刷新。只有状态变量才能触发UI刷新)、@State、@Link、@Prop、@Provide、@Consume、@ObjectLink、@StorageLink、@StorageProp、@LocalStorageLink和@LocalStorageProp去初始化子组件中的@Prop变量。
用于初始化子组件@Prop支持去初始化子组件中的常规变量、@State、@Link、@Prop、@Provide。
是否支持组件外访问@Prop装饰的变量是私有的,只能在组件内访问。

初始化规则图示
在这里插入图片描述

三、@Link装饰器

@Link装饰器:父子双向同步
子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。

说明
从API version 9开始,该装饰器支持在ArkTS卡片中使用。
从API version 11开始,该装饰器支持在元服务中使用。

3.1 概述

@Link装饰的变量与其父组件中的数据源共享相同的值。

3.2 限制条件

@Link装饰器不能在@Entry装饰的自定义组件中使用。

3.3 装饰器使用规则说明
@Link变量装饰器说明
装饰器参数
同步类型双向同步。
父组件中的状态变量可以与子组件@Link建立双向同步,当其中一方改变时,另外一方能够感知到变化。
允许装饰的变量类型Object、class、string、number、boolean、enum类型,以及这些类型的数组。
支持Date类型。
API11及以上支持Map、Set类型。
支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。
类型必须被指定,且和双向绑定状态变量的类型相同。
支持类型的场景请参考观察变化。
不支持any。
API11及以上支持上述支持类型的联合类型,比如string | number, string | undefined 或者 ClassA | null,示例见Link支持联合类型实例。
注意
当使用undefined和null的时候,建议显式指定类型,遵循TypeScript类型校验,比如:@Link a : string | undefined。
被装饰变量的初始值无,禁止本地初始化。
3.4 变量的传递/访问规则说明
传递/访问说明
从父组件初始化和更新必选。与父组件@State, @StorageLink和@Link 建立双向绑定。允许父组件中@State、@Link、@Prop、@Provide、@Consume、@ObjectLink、@StorageLink、@StorageProp、@LocalStorageLink和@LocalStorageProp装饰变量初始化子组件@Link。
从API version 9开始,@Link子组件从父组件初始化@State的语法为Comp({ aLink: this.aState })。同样Comp({aLink: $aState})也支持。
用于初始化子组件允许,可用于初始化常规变量、@State、@Link、@Prop、@Provide。
是否支持组件外访问私有,只能在所属组件内访问。

初始化规则图示
在这里插入图片描述

3.5 观察变化和行为表现

观察变化

  • 当装饰的数据类型为boolean、string、number类型时,可以同步观察到数值的变化,示例请参考简单类型和类对象类型的@Link。
  • 当装饰的数据类型为class或者Object时,可以观察到赋值和属性赋值的变化,即Object.keys(observedObject)返回的所有属性,示例请参考简单类型和类对象类型的@Link。
  • 当装饰的对象是array时,可以观察到数组添加、删除、更新数组单元的变化,示例请参考数组类型的@Link。
  • 当装饰的对象是Date时,可以观察到Date整体的赋值,同时可通过调用Date的接口setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime, setUTCFullYear, setUTCMonth, setUTCDate, setUTCHours, setUTCMinutes, setUTCSeconds, setUTCMilliseconds 更新Date的属性。
  • 当装饰的变量是Map时,可以观察到Map整体的赋值,同时可通过调用Map的接口set, clear, delete 更新Map的值。详见装饰Map类型变量。
  • 当装饰的变量是Set时,可以观察到Set整体的赋值,同时可通过调用Set的接口add, clear, delete 更新Set的值。详见装饰Set类型变量。
@Component
struct DateComponent {
  @Link selectedDate: Date;

  build() {
    Column() {
      Button(`child increase the year by 1`).onClick(() => {
        this.selectedDate.setFullYear(this.selectedDate.getFullYear() + 1)
      })
      Button('child update the new date')
        .margin(10)
        .onClick(() => {
          this.selectedDate = new Date('2023-09-09')
        })
      DatePicker({
        start: new Date('1970-1-1'),
        end: new Date('2100-1-1'),
        selected: this.selectedDate
      })
    }

  }
}

@Entry
@Component
struct ParentComponent {
  @State parentSelectedDate: Date = new Date('2021-08-08');

  build() {
    Column() {
      Button('parent increase the month by 1')
        .margin(10)
        .onClick(() => {
          this.parentSelectedDate.setMonth(this.parentSelectedDate.getMonth() + 1)
        })
      Button('parent update the new date')
        .margin(10)
        .onClick(() => {
          this.parentSelectedDate = new Date('2023-07-07')
        })
      DatePicker({
        start: new Date('1970-1-1'),
        end: new Date('2100-1-1'),
        selected: this.parentSelectedDate
      })

      DateComponent({ selectedDate:this.parentSelectedDate })
    }
  }
}

http://www.kler.cn/a/409671.html

相关文章:

  • 替换Nacos的MySQL驱动
  • 【第十课】Rust并发编程(一)
  • 使用go实现流式输出
  • 【人工智能】深度学习入门:用TensorFlow实现多层感知器(MLP)模型
  • MySQL底层概述—1.InnoDB内存结构
  • RabbitMQ和RocketMQ相关面试题
  • HandyControl简单应用
  • 电脑桌面备忘录提醒,备忘录提醒工具设置
  • 微服务系统架构图
  • 健身房小程序服务渠道开展
  • 如何用通义灵码快速绘制流程图?
  • 网络爬虫——分布式爬虫架构
  • 解读 Keep-Alive:CSDN 项目实例分析
  • Spring Boot框架:英语知识网站构建指南
  • 麒麟系统状态监控
  • error LNK2001: 无法解析的外部符号 memcpy strcmp strlen
  • FPGA经验谈系列文章——8、复位的设计
  • Spring Boot OA:企业办公自动化的创新之路
  • svn-git下载
  • 去重判断 是!vis[i - 1] 而非 vis[i - 1] 详解
  • 在 ARM 平台上如何实现Linux系统的1秒启动
  • 菊风视频能力平台开发服务正式入驻华为云云商店,成为华为云联营联运合作伙伴
  • GPT-4 Technical Report——GPT-4技术报告
  • Spring Boot Starter依赖
  • 【创建型设计模式】工厂模式
  • 心情追忆-首页“毒“鸡汤AI自动化