鸿蒙:@State装饰器

@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。

在状态变量相关装饰器中,@State是最基础的,使变量拥有状态属性的装饰器,它也是大部分状态变量的数据源。从API version 9开始,该装饰器支持在ArkTS卡片中使用。

一、概述

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

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

  • @State装饰的变量与子组件中的@Prop、@Link或@ObjectLink装饰变量之间建立单向或双向数据同步。
  • @State装饰的变量生命周期与其所属自定义组件的生命周期相同。

二、装饰器使用规则说明

|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| @State变量装饰器 | 说明 |
| 装饰器参数 | 无 |
| 同步类型 | 不与父组件中任何类型的变量同步。 |
| 允许装饰的变量类型 | Object、class、string、number、boolean、enum类型,以及这些类型的数组。 类型必须被指定。 不支持any,不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。 说明:建议不要装饰Date类型,应用可能会产生异常行为。不支持Length、ResourceStr、ResourceColor类型,Length、ResourceStr、ResourceColor为简单类型和复杂类型的联合类型。 |
| 被装饰变量的初始值 | 必须本地初始化。 |

三、使用场景

(1)装饰简单类型的变量

以下示例为@State装饰的简单类型,count被@State装饰成为状态变量,count的改变引起Button组件的刷新:

  1. 当状态变量count改变时,查询到只有Button组件关联了它;

  2. 执行Button组件的更新方法,实现按需刷新。

    TypeScript 复制代码
    @Entry
    @Component
    struct MyComponent {
      @State count: number = 0
    
      build() {
        Button(`click times: ${this.count}`)
          .width(200)
          .height(80)
          .fontSize(20)
          .margin(10)
          .onClick(() => {
            this.count += 1
          })
      }
    }

    (2)装饰Class对象类型的变量

  • 自定义组件MyComponent定义了被@State装饰的状态变量count和title,其中title的类型为自定义类Model。如果count或title的值发生变化,则查询MyComponent中使用该状态变量的UI组件,并进行重新渲染。

  • EntryComponent中有多个MyComponent组件实例,第一个MyComponent内部状态的更改不会影响第二个MyComponent。

TypeScript 复制代码
class Model {
  public value: string;

  constructor(value: string) {
    this.value = value;
  }
}

@Entry
@Component
struct EntryComponent {
  build() {
    Column() {
      // 此处指定的参数都将在初始渲染时覆盖本地定义的默认值,并不是所有的参数都需要从父组件初始化
      MyComponent({ count: 1, increaseBy: 2 })
      MyComponent({ title: new Model('Hello, World 2'), count: 7 })
    }
  }
}

@Component
struct MyComponent {
  @State title: Model = new Model('Hello World')
  @State count: number = 0
  private increaseBy: number = 1

  build() {
    Column() {
      Text(`${this.title.value}`)
        .height(80)
      Divider()
      Button(`Click to change title`).onClick(() => {
        // @State变量的更新将触发上面的Text组件内容更新
        this.title.value = this.title.value === 'Hello ArkUI' ? 'Hello World' : 'Hello ArkUI'
      })
        .height(80)
        .width(250)
        .margin(5)

      Button(`Click to increase count=${this.count}`).onClick(() => {
        // @State变量的更新将触发该Button组件的内容更新
        this.count += this.increaseBy
      })
        .height(80)
        .width(250)
        .margin(5)
    }
  }
}

当点击两个"Click to change title"按钮时,对应的标题会在"Hello World"和"Hello ArkUI"之间进行切换。

在第一个MyComponent 中点击第二个按钮时会自动加2;在第二个MyComponent 中点击第二个按钮时会自动加1。

从该示例中,我们可以了解到@State变量首次渲染的初始化流程:

  1. 使用默认的本地初始化:

|-------------------------------------------------------------------------|
| @State title: Model = new Model('Hello World') @State count: number = 0 |

  1. 对于@State来说,命名参数机制传递的值并不是必选的,如果没有命名参数传值,则使用本地初始化的默认值:

|------------------------------------------|
| MyComponent({ count: 1, increaseBy: 2 }) |

相关推荐
以太浮标1 天前
华为eNSP模拟器综合实验之-DHCP服务中继配置案例
网络·华为·智能路由器·信息与通信
游戏技术分享1 天前
【鸿蒙游戏技术分享 第75期】AGC后台批量导入商品失败,提示“参数错误”
游戏·华为·harmonyos
No Silver Bullet2 天前
HarmonyOS NEXT开发进阶(十七):WebView 拉起 H5 页面
华为·harmonyos
liuhaikang2 天前
【鸿蒙HarmonyOS Next App实战开发】口语小搭档——应用技术实践
harmonyos
北方的流星2 天前
华为交换机MSTP和VRRP综合应用配置
运维·网络·华为
C雨后彩虹2 天前
简易内存池
java·数据结构·算法·华为·面试
liuhaikang2 天前
鸿蒙VR视频播放库——md360player
音视频·vr·harmonyos
北方的流星2 天前
华为交换机IPv6静态路由、默认路由、RIPng和OSPFv3路由配置
运维·网络·华为
飞露2 天前
鸿蒙Preview预览文件失败原因
华为·harmonyos
夏小鱼的blog2 天前
【HarmonyOS应用开发入门】第五期:状态管理V2入门 - 1
harmonyos·状态管理