在鸿蒙系统(HarmonyOS)的应用开发中,状态管理是构建响应式 UI 的核心机制,而装饰器(Decorator)是实现状态管理的重要工具。这些装饰器能够更便捷地管理组件状态,并实现状态与 UI 的自动同步。以下是鸿蒙系统中常用状态管理装饰器的详细用法:

        1. @State:组件内部状态

    @State 用于装饰组件内部的状态变量,当变量值发生变化时,会引起UI更新

        特点

  • 仅在当前组件内部生效,是组件的私有状态

  • 变量变化引起组件及其子组件的 UI 更新

  • 支持多种数据类型:基本类型(number、string、boolean)、对象、数组等

    @Entry
    @Component
    struct StateDemo {
      // 用@State装饰内部状态变量
      @State count: number = 0;
    
      build() {
        Column() {
          Text(`当前计数: ${this.count}`)
            .fontSize(20)
          
          Button('增加计数')
            .onClick(() => {
              // 状态变化会自动触发UI更新
              this.count++;
            })
        }
        .padding(20)
      }
    }

    • 2. @Prop:父子组件单向同步

      @Prop 用于子组件接收父组件传递的数据,并建立单向数据绑定(父组件数据变化会同步到子组件,但子组件无法直接修改父组件的状态)。

      特点

    • 子组件修改@Prop变量时,仅影响自身,不会反向同步到父组件

    • 父组件传递的状态必须是被@State@Link等装饰的状态变量

    • 子组件依赖父组件的状态,是 "单向数据流"

    • // 顶层组件(提供状态)
      @Entry
      @Component
      struct GrandparentComponent {
        // 提供可被跨层级消费的状态
        @Provide('themeColor') color: string = 'red';
      
        build() {
          Column() {
            ParentComponent()
            Button('切换颜色')
              .onClick(() => {
                this.color = this.color === 'red' ? 'blue' : 'red';
              })
          }
        }
      }
      
      // 中间组件(无需传递状态)
      @Component
      struct ParentComponent {
        build() {
          Column() {
            ChildComponent()
          }
        }
      }
      
      // 深层子组件(消费状态)
      @Component
      struct ChildComponent {
        // 消费顶层组件提供的状态
        @Consume('themeColor') textColor: string;
      
        build() {
          Text('跨层级共享的文本')
            .fontColor(this.textColor)
            .fontSize(20)
        }
      }

      3. @ObjectLink 与 @Observed:对象类型状态管理

      当需要管理复杂对象类型的状态时,@Observed 用于装饰类,@ObjectLink 用于建立对对象的引用,实现对象属性变化的监听。

      • @Observed 装饰类,@ObjectLink 装饰该类的实例,且@ObjectLink 不能初始化值

      • 解决嵌套属性更新不能引起UI更新的情况,对象属性变化时,会触发 UI 更新

        // 用@Observed装饰类,使其属性变化可被观察
        @Observed
        class User {
          name: string;
          age: number;
        
          constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
          }
        }
        
        @Component
        struct UserComponent {
          // 用@ObjectLink引用User对象
          @ObjectLink user: User;
        
          build() {
            Column() {
              Text(`姓名: ${this.user.name}`)
              Text(`年龄: ${this.user.age}`)
              Button('增加年龄')
                .onClick(() => {
                  this.user.age++; // 对象属性变化会触发UI更新
                })
            }
          }
        }
        
        @Entry
        @Component
        struct ParentComponent {
          @State user: User = new User('张三', 20);
        
          build() {
            Column() {
              UserComponent({ user: this.user })
            }
          }
        }

    4. @Link:父子组件双向同步

    @Link 用于实现父子组件间的双向数据绑定,子组件对状态的修改会同步回父组件。

    • 特点

    • 跨层级共享,避免 "props 穿透" 问题

    • 一对多关系,一个@Provide可以被多个@Consume消费

    • @Link不能自己初始化数据,不能通过foreach循环传递数据

      // 子组件
      @Component
      struct ChildComponent {
        // 用@Link实现双向绑定
        @Link count: number;
      
        build() {
          Button('子组件修改计数: ' + this.count)
            .onClick(() => {
              this.count++; // 子组件修改会同步到父组件
            })
        }
      }
      
      // 父组件
      @Entry
      @Component
      struct ParentComponent {
        @State parentCount: number = 0;
      
        build() {
          Column() {
            Text(`父组件计数: ${this.parentCount}`)
            // 传递状态时需要用$符号表示双向绑定
            ChildComponent({ count: $parentCount })
          }
        }
      }

      5. @Provide 与 @Consume:跨组件层级共享

      @Provide 和 @Consume 用于跨多层级组件传递数据和状态。

      特点

    • 本质是对父组件状态的引用,子组件修改会直接影响父组件

    • 父组件必须传递@State装饰的状态给子组件的@Link变量

    • 双向传递数据,父子组件状态实时同步

    • 父组件中的属性名和子组件定义的变量保持一致

      // 子组件
      @Component
      struct ChildComponent {
        // 用@Prop接收父组件传递的状态
        @Prop count: number;
      
        build() {
          Column() {
            Text(`子组件计数: ${this.count}`)
            Button('子组件增加')
              .onClick(() => {
                // 仅修改子组件内部的count,不影响父组件
                this.count++;
              })
          }
        }
      }
      
      // 父组件
      @Entry
      @Component
      struct ParentComponent {
        @State parentCount: number = 0;
      
        build() {
          Column() {
            Text(`父组件计数: ${this.parentCount}`)
            Button('父组件增加')
              .onClick(() => {
                this.parentCount++; // 父组件修改会同步到子组件
              })
            // 将父组件状态传递给子组件
            ChildComponent({ count: this.parentCount })
          }
          .padding(20)
        }
      }

总结:

  • 复杂对象管理:@Observed + @ObjectLink

  • 跨层级共享:@Provide + @Consume

  • 父子组件通信:@Prop(单向)、@Link(双向)

  • 组件内部状态:@State

  • @Provide@Consume变量名保持一致,且@Consume不能初始化值

合理使用这些装饰器可以大幅提升代码的可维护性,并确保 UI 与状态的实时同步,是鸿蒙应用开发的基础技能。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐