鸿蒙HarmonyOS状态管理装饰器详解

发布于:2025-08-31 ⋅ 阅读:(22) ⋅ 点赞:(0)

装饰器概述

装饰器 说明 使用场景
@Prop 单向同步 父子组件间单向数据传递
@Link 双向同步 父子组件间双向数据同步
@Provide/@Consume 跨层级数据同步 祖先和后代组件间数据同步
@Observed 类装饰器 使类具备响应式能力
@ObjectLink 对象属性同步 与@Observed配合实现对象属性同步

完整示例演示

import { BusinessError } from '@ohos.base';

// 定义一个被@Observed装饰的类
@Observed
class User {
  name: string;
  age: number;
  
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

@Entry
@Component
struct MainPage {
  @State message: string = 'Hello HarmonyOS';
  @State count: number = 0;
  @State isActive: boolean = true;
  @State user: User = new User('张三', 25);
  @Provide totalScore: number = 100;

  build() {
    Column({ space: 20 }) {
      Text(this.message)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
      
      Divider()
      
      // 显示当前计数
      Text(`计数: ${this.count}`)
        .fontSize(20)
      
      // 显示用户信息
      Text(`用户: ${this.user.name}, 年龄: ${this.user.age}`)
        .fontSize(20)
      
      // 显示总分
      Text(`总分: ${this.totalScore}`)
        .fontSize(20)
        .margin({ top: 10 })
      
      Divider()
      
      // 使用@Prop的子组件
      PropChildComponent({ propMessage: this.message })
        .margin({ top: 10 })
      
      // 使用@Link的子组件
      LinkChildComponent({ linkCount: $count })
        .margin({ top: 10 })
      
      // 使用@ObjectLink的子组件
      ObjectLinkChildComponent({ objectLinkUser: this.user })
        .margin({ top: 10 })
      
      // 使用@Consume的子组件
      ConsumeChildComponent()
        .margin({ top: 10 })
      
      Button('父组件修改数据')
        .width('80%')
        .onClick(() => {
          this.count++;
          this.user.age++;
          this.totalScore += 10;
          this.message = `父组件修改于 ${new Date().toLocaleTimeString()}`;
        })
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

// 使用@Prop的子组件
@Component
struct PropChildComponent {
  @Prop propMessage: string;
  
  build() {
    Column() {
      Text('@Prop子组件')
        .fontSize(18)
        .fontColor(Color.Blue)
      
      Text(this.propMessage)
        .fontSize(16)
        .margin({ top: 5 })
      
      Button('修改@Prop数据(不会同步回父组件)')
        .width('90%')
        .margin({ top: 10 })
        .onClick(() => {
          this.propMessage = `子组件修改于 ${new Date().toLocaleTimeString()}`;
        })
    }
    .width('100%')
    .padding(10)
    .backgroundColor(Color.White)
    .borderRadius(10)
  }
}

// 使用@Link的子组件
@Component
struct LinkChildComponent {
  @Link linkCount: number;
  
  build() {
    Column() {
      Text('@Link子组件')
        .fontSize(18)
        .fontColor(Color.Green)
      
      Text(`计数: ${this.linkCount}`)
        .fontSize(16)
        .margin({ top: 5 })
      
      Button('增加计数(会同步回父组件)')
        .width('90%')
        .margin({ top: 10 })
        .onClick(() => {
          this.linkCount++;
        })
    }
    .width('100%')
    .padding(10)
    .backgroundColor(Color.White)
    .borderRadius(10)
  }
}

// 使用@ObjectLink的子组件
@Component
struct ObjectLinkChildComponent {
  @ObjectLink objectLinkUser: User;
  
  build() {
    Column() {
      Text('@ObjectLink子组件')
        .fontSize(18)
        .fontColor(Color.Orange)
      
      Text(`用户: ${this.objectLinkUser.name}, 年龄: ${this.objectLinkUser.age}`)
        .fontSize(16)
        .margin({ top: 5 })
      
      Button('增加年龄(会同步回父组件)')
        .width('90%')
        .margin({ top: 10 })
        .onClick(() => {
          this.objectLinkUser.age++;
        })
    }
    .width('100%')
    .padding(10)
    .backgroundColor(Color.White)
    .borderRadius(10)
  }
}

// 使用@Consume的子组件
@Component
struct ConsumeChildComponent {
  @Consume totalScore: number;
  
  build() {
    Column() {
      Text('@Consume子组件')
        .fontSize(18)
        .fontColor(Color.Red)
      
      Text(`总分: ${this.totalScore}`)
        .fontSize(16)
        .margin({ top: 5 })
      
      Button('减少分数(会同步到所有@Provide)')
        .width('90%')
        .margin({ top: 10 })
        .onClick(() => {
          this.totalScore -= 5;
        })
    }
    .width('100%')
    .padding(10)
    .backgroundColor(Color.White)
    .borderRadius(10)
  }
}

各装饰器详细说明

1. @Prop 装饰器

特点

  • 单向数据同步:从父组件到子组件

  • 子组件内修改不会同步回父组件

  • 适用于展示型组件

使用场景
当父组件需要传递数据给子组件,但子组件不需要修改父组件数据时使用。

2. @Link 装饰器

特点

  • 双向数据同步:父子组件间双向同步

  • 子组件修改会同步回父组件

  • 需要使用$语法传递引用

使用场景
当子组件需要修改父组件数据并同步回父组件时使用。

3. @Provide 和 @Consume 装饰器

特点

  • 跨层级数据同步:祖先组件和后代组件间直接同步

  • 不需要逐层传递数据

  • 任何一方修改都会同步到另一方

使用场景
当需要跨越多层组件传递数据时使用,避免"属性 drilling"问题。

4. @Observed 和 @ObjectLink 装饰器

特点

  • @Observed 装饰类,使其具备响应式能力

  • @ObjectLink 装饰对象属性,实现对象属性的双向同步

  • 用于复杂对象的数据同步

使用场景
当需要同步对象的属性而不是整个对象时使用。

使用建议

  1. 简单数据传递使用 @Prop 或 @Link

  2. 跨层级数据共享使用 @Provide 和 @Consume

  3. 对象属性同步使用 @Observed 和 @ObjectLink

  4. 根据数据流方向选择合适的装饰器

  5. 避免过度使用 @Provide 和 @Consume,以免造成数据流难以追踪

这个示例展示了各种装饰器的基本用法和区别,您可以通过运行代码并点击各个按钮来观察不同装饰器的行为差异。


网站公告

今日签到

点亮在社区的每一天
去签到