前言

在鸿蒙 ArkUI 声明式开发中,页面不会主动感知普通变量的变化。如果想实现修改数据后 UI 自动刷新,就必须使用 @State 装饰器。本文结合课堂 4 组实训案例,从布尔开关切换、数字计数器、输入框双向绑定、登录表单校验四个场景,完整讲解@State的作用、语法、使用规则与实战逻辑。

一、@State 核心基础概念

1. 作用

@State 用来装饰组件内部私有状态变量,建立「数据 - UI」双向响应绑定:

  1. 变量发生修改时,自动触发当前组件重新渲染;
  2. UI 交互(按钮点击、输入框输入)可以同步修改变量;
  3. 仅作用于当前自定义组件,属于组件内局部状态。

2. 基础语法

@State 变量名: 类型 = 初始值

示例:

@State isShow: boolean = true
@State num: number = 0
@State inputText: string = ""

3. 触发更新的规则

只有直接赋值修改才会触发页面刷新:

  • 布尔取反:this.isShow = !this.isShow
  • 数字增减:this.num++ / this.num--
  • 字符串赋值:this.inputText = value

二、案例 1:布尔状态 —— 开关文字切换(点击切换显示文本)

需求效果

页面默认显示红色文字「状态已开启」;点击按钮后文字、文字颜色同步切换为「状态已关闭」黄色,再次点击复原。

完整代码

@Entry
@Component
struct StateDemo{
  @State isShow:boolean=true
  private num:number=1
  build() {
    Column({space:60}){
      Text(this.isShow?"状态已开启":"状态已关闭")
        .fontSize(36)
        .fontWeight(FontWeight.Bold)
        .fontColor(this.isShow?Color.Red:Color.Yellow)
      Button("点击切换状态")
        .width('100%')
        .height(50)
        .fontSize(24)
        .backgroundColor(0x007dff)
        .onClick(()=>{
          this.isShow=!this.isShow
        })
    }
    .width('100%')
    .height('100%')
    .padding(30)
  }
}

效果

核心知识点

  1. @State isShow 保存布尔状态;
  2. 三元运算符 条件 ? 真值 : 假值 实现 UI 动态渲染;
  3. 按钮onClick对状态变量重新赋值,页面自动同步变化;
  4. 普通private num修改不会刷新页面,只有@State修饰变量才具备响应式能力。

三、案例 2:数字状态 —— 数值计数器(限定 0~10 范围)

需求效果

页面展示当前数字,两个按钮分别实现递增、递减;数字最小为 0、最大为 10,超出边界不再变化。

完整代码

@Entry
@Component
struct StateDemo2{
  @State num:number=0
  build() {
    Column({space:30 }){
      Text(`当前的数是:${this.num}`)
        .fontSize(35)
        .fontWeight(FontWeight.Bolder)
      Row({space:30}){
        Button('-递减')
          .width('47%')
          .height(50)
          .fontSize(26)
          .onClick(()=>{
            if (this.num>0) {
              this.num--
            }
          })
        Button("+递加")
          .width('47%')
          .height(50)
          .fontSize(26)
          .onClick(()=>{
            if (this.num<10) {
              this.num++
            }
          })
      }
      .width('100%')
      Text("数值范围:0-10")
        .fontSize(16)
        .fontColor(Color.Gray)
    }
  }
}

效果

核心知识点

  1. 数字变量被@State修饰,num++/num--赋值后页面立刻更新;
  2. 通过if判断限制数值区间,防止越界;
  3. 模板字符串 `${this.num}` 动态拼接数字文本;
  4. Row 布局均分两个按钮,width('47%')留出间隔避免挤压。

四、案例 3:字符串状态 ——TextInput 输入双向绑定

需求效果

输入框输入任意文字,上方 Text 实时同步展示输入内容,实现输入与显示双向联动。

完整代码

@Entry
@Component
struct StateDemo3{
  @State inputText:string=""
  build() {
    Column({space:30}){
      Text(`你输入的内容是:\n${this.inputText}`)
        .fontSize(25)
        .width('100%')
        .textAlign(TextAlign.Center)
        .fontColor(Color.Blue)

      TextInput({text:this.inputText,placeholder:"请输入任意内容"})
        .width('100%')
        .height(50)
        .borderRadius(10)
        .onChange((value:string)=>{
          this.inputText=value
        })

    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

效果

核心知识点

  1. TextInput通过text绑定@State字符串变量,实现数据同步;
  2. onChange监听输入内容变化,实时赋值给状态变量;
  3. 上方 Text 直接读取状态变量,做到输入实时预览
  4. placeholder设置输入框空白提示文字。

五、案例 4:综合实战 —— 登录表单(多状态联合校验)

需求说明

同时使用两个@State字符串变量存储账号、密码,实现:

  1. 两个输入框双向绑定账号、密码;密码框隐藏明文;
  2. 登录按钮点击校验账号密码,匹配弹出成功弹窗,不匹配弹出失败弹窗;
  3. 清除按钮一键清空两个输入框内容,UI 同步清空。

完整代码

@Entry
@Component
struct EventDemo{
  @State username:string=""
  @State password:string=""
  build() {
    Column({space:30}) {
      Text('用户登录')
        .fontSize(32)
        .fontWeight(FontWeight.Bolder)
        .margin({ top: 20, bottom: 30 })
      TextInput({ text: this.username, placeholder: '请输入账号' })
        .width(320)
        .height(52)
        .borderRadius(12)
        .fontSize(16)
        .onChange((value: string) => {
          this.username = value
        })
      TextInput({ text: this.password, placeholder: "请输入密码:" })
        .type(InputType.Password)
        .width(320)
        .height(52)
        .borderRadius(12)
        .fontSize(16)
        .onChange((value: string) => {
          this.password = value
        })
      Row({space:30}) {
        Button("立即登录")
          .width('40%')
          .height(52)
          .backgroundColor(0x007dff)
          .fontSize(18)
          .borderRadius(12)
          .margin({ bottom: 80 })
          .onClick(() => {
            if (this.username == 'root' && this.password == 'root') {
              AlertDialog.show({
                title: '登录成功',
                message: `欢迎你,${this.username}`
              })
            } else {
              AlertDialog.show({
                title: '登录失败',
                message: '用户名或者密码错误'
              })
            }
          })

        Button('清除信息')
          .width('40%')
          .height(52)
          .backgroundColor(0x007dff)
          .fontSize(18)
          .borderRadius(12)
          .margin({ bottom: 80 })
          .onClick(()=>{
            this.username=""
            this.password=""
          })
      }
    }
    .width('100%')
    .height('100%')
  }
}

效果

核心知识点

  1. 支持同时定义多个@State变量,多表单字段独立管理;
  2. InputType.Password 实现密码框隐藏文字;
  3. 多状态联合判断:&& 同时校验账号、密码两个状态;
  4. 一键清空:直接给两个@State字符串赋值空字符串,输入框实时清空;
  5. AlertDialog弹窗展示状态校验结果。

六、@State 使用总结与注意事项

1. 适用场景

  • 按钮点击切换 UI(开关、弹窗、文字切换)
  • 计数器、打分、数值调整
  • 输入框、单选多选、登录表单等多字段表单交互
  • 组件内部临时存储、页面局部动态数据

2. 关键使用规则

  1. 仅能修饰组件内私有变量,不能修饰全局变量;
  2. 必须赋初始值,支持boolean/number/string/ 数组 / 对象;
  3. 只有直接赋值才会触发 UI 刷新,只读访问不会更新页面;
  4. 普通private变量修改不会刷新界面,无响应式能力;
  5. 作用域仅限当前struct组件,跨组件传值需要@Prop/@Link
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐