鸿蒙ArkUI框架中的状态管理

在ArkUI框架中,状态管理是构建动态应用的核心。以下是组件级别应用级别状态管理装饰器的分类、用途及区别的总结,结合了思考过程中的关键点:

一、组件级别状态管理

1. @State

  • 用途:组件内部私有状态,变化触发UI更新。
  • 示例:按钮的点击状态、计数器数值。
  • 特点:只能初始化一次,单向数据流(组件内修改)。

代码示例

javascript 复制代码
@Component
struct CounterButton {
  @State count: number = 0; // 组件内部状态

  build() {
    Button(`点击次数:${this.count}`)
      .onClick(() => {
        this.count++; // 修改@State变量自动更新UI
      })
  }
}

2. @Prop

  • 用途:父组件向子组件传递数据(单向)。
  • 特点:需通过父组件回调更新数据。
  • 示例:显示父组件传递的文本,子组件不可直接修改。

代码示例

javascript 复制代码
// 父组件
@Component
struct ParentComponent {
  @State parentCount: number = 0;

  build() {
    Column() {
      ChildComponent({ countProp: this.parentCount }) // 传递数据
      Button("父组件增加").onClick(() => this.parentCount++)
    }
  }
}

// 子组件
@Component
struct ChildComponent {
  @Prop countProp: number; // 单向接收父组件数据

  build() {
    Text(`来自父组件的值:${this.countProp}`)
  }
}

  • 用途:父子组件双向数据绑定。
  • 特点 :双向同步,类似Vue的v-model
  • 示例:共享开关状态,子组件直接修改影响父组件。

代码示例

javascript 复制代码
// 父组件
@Component
struct ParentComponent {
  @State sharedCount: number = 0;

  build() {
    Column() {
      ChildComponent({ countLink: $sharedCount }) // 双向绑定
      Text(`父组件值:${this.sharedCount}`)
    }
  }
}

// 子组件
@Component
struct ChildComponent {
  @Link countLink: number; // 双向绑定变量

  build() {
    Button("子组件修改").onClick(() => {
      this.countLink++; // 修改会同步到父组件
    })
  }
}

4. @Provide / @Consume

  • 用途:跨层级组件数据共享(祖先→后代)。
  • 示例:主题颜色全局设置。
  • 特点:避免逐层传递,类似React Context。

代码示例

javascript 复制代码
// 祖先组件
@Component
struct AncestorComponent {
  @Provide themeColor: string = 'blue'; // 提供数据

  build() {
    Column() {
      ChildComponent()
    }
  }
}

// 后代组件
@Component
struct ChildComponent {
  @Consume themeColor: string; // 消费数据

  build() {
    Text(`当前主题色:${this.themeColor}`)
      .fontColor(this.themeColor)
  }
}

  • 用途:观察嵌套对象属性变化。
  • 特点@Observed装饰类,@ObjectLink引用实例。
  • 示例 :用户对象({name: string})属性更新。

代码示例

javascript 复制代码
@Observed // 装饰类
class User {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

@Component
struct UserProfile {
  @ObjectLink user: User; // 引用被观察对象

  build() {
    Column() {
      Text(`姓名:${this.user.name}`)
      Button("修改年龄").onClick(() => {
        this.user.age++; // 修改会触发UI更新
      })
    }
  }
}

6. @Style

  • 用途:定义可复用的组件样式。
  • 示例:统一按钮样式(颜色、边距)。

代码示例

javascript 复制代码
@Styles function customButtonStyle() {
  .width(120)
  .height(40)
  .backgroundColor(Color.Blue)
  .fontColor(Color.White)
}

@Component
struct StyledButton {
  build() {
    Button("样式按钮")
      .useStyle(customButtonStyle) // 应用样式
  }
}

7. @Builder / @BuilderParam

  • 用途:构建可复用的UI片段或动态插入布局。
  • 示例:自定义卡片布局,父组件传递头部Builder。
  • 区别@Builder定义结构,@BuilderParam接收结构作为参数。

代码示例

javascript 复制代码
@Component
struct CustomCard {
  @BuilderParam header: () => void; // 接收Builder参数

  build() {
    Column() {
      this.header() // 插入自定义头部
      Text("卡片内容...")
    }
  }
}

// 使用组件时传递Builder
CustomCard({
  header: () => {
    Text("自定义标题")
      .fontSize(20)
      .fontColor(Color.Red)
  }
})

8. @Extend

  • 用途:扩展组件样式(如全局字体)。
  • 示例:统一所有文本的字体大小和颜色。

代码示例

javascript 复制代码
@Extend(Text) function boldText() {
  .fontWeight(FontWeight.Bold)
  .fontColor('#333')
}

@Component
struct ExtendedText {
  build() {
    Column() {
      Text("普通文本")
      Text("加粗文本").useStyle(boldText) // 应用扩展样式
    }
  }
}

二、应用级别状态管理

1. @LocalStorage

  • 用途:页面级临时存储(页面关闭后可能保留)。
  • 示例:表单草稿保存。

补充知识点: @LocalStorageProp / @LocalStorageLink

区别:前者单向同步,后者双向绑定页面存储数据。

代码示例

javascript 复制代码
// 页面A
@Entry
@Component
struct PageA {
  @LocalStorage('formData') formData: string = '';

  build() {
    TextInput(this.formData)
      .onChange((value) => {
        this.formData = value; // 数据保存到LocalStorage
      })
  }
}

// 页面B可读取同一LocalStorage
@Component
struct PageB {
  @LocalStorage('formData') formData: string;

  build() {
    Text(`保存的数据:${this.formData}`)
  }
}

2. @AppStorage

  • 用途:全局状态存储(应用生命周期内有效)。
  • 示例:用户登录Token。

补充知识点: @StorageProp / @StorageLink

用途 :绑定到AppStorage中的具体键。

区别@StorageProp单向,@StorageLink双向。

代码示例

javascript 复制代码
// 全局存储用户Token
@AppStorage.setOrCreate('userToken', '') // 初始化

@Component
struct LoginComponent {
  @StorageLink('userToken') token: string; // 双向绑定

  build() {
    Button("登录").onClick(() => {
      this.token = 'abc123'; // 修改全局状态
    })
  }
}

// 其他页面读取
@Component
struct ProfilePage {
  @StorageProp('userToken') token: string; // 单向读取

  build() {
    Text(`Token: ${this.token}`)
  }
}

3. @PersistentStorage

  • 用途:持久化存储(应用重启保留)。
  • 示例:用户偏好设置(语言、主题)。

代码示例

javascript 复制代码
@PersistentStorage.setOrCreate('settings', { theme: 'light', fontSize: 16 })

@Component
struct SettingsPage {
  @StorageLink('theme') theme: string;
  @StorageLink('fontSize') fontSize: number;

  build() {
    Column() {
      Button("切换主题").onClick(() => {
        this.theme = this.theme === 'light' ? 'dark' : 'light';
      })
      Slider({ min: 12, max: 24 })
        .value(this.fontSize)
        .onChange((value) => {
          this.fontSize = value;
        })
    }
  }
}

4. @Environment

  • 用途:访问环境变量(如主题、语言)。
  • 示例:根据系统主题切换应用外观。

代码示例

javascript 复制代码
@Component
struct ThemeAwareComponent {
  @Environment('currentTheme') theme: string;

  build() {
    Text("主题敏感文本")
      .fontColor(this.theme === 'dark' ? Color.White : Color.Black)
      .backgroundColor(this.theme === 'dark' ? Color.Black : Color.White)
  }
}

三、关键区别与选择

  • 作用域

    • 组件级:@State@Prop等用于组件或父子通信。
    • 应用级:@AppStorage@PersistentStorage等跨页面共享。
  • 数据流

    • 单向:@Prop@LocalStorageProp(父→子/存储→组件)。
    • 双向:@Link@LocalStorageLink(父子/组件与存储同步)。
  • 持久性

    • 临时:@State@LocalStorage(页面级)。
    • 持久:@PersistentStorage(设备存储)。
  • 使用场景

    • 简单组件状态 → @State
    • 跨组件共享 → @Provide/@Consume
    • 全局配置 → @AppStorage + @StorageLink
    • 复杂对象监听 → @Observed + @ObjectLink


四、最佳实践总结

  1. 简单交互优先使用@State:适合按钮状态、临时计数等
  2. 父子通信选择@Prop/@Link :单向传递用@Prop,双向同步用@Link
  3. 跨层级共享数据用@Provide/@Consume:避免多级传递的麻烦
  4. 全局状态使用@AppStorage:如用户登录状态、主题配置
  5. 复杂对象监听用@Observed+@ObjectLink:确保嵌套属性变化触发更新
  6. 持久化数据用@PersistentStorage:用户设置、历史记录等需要长期保存的数据

官方文档是更全面的参考:
HarmonyOS ArkUI 文档

相关推荐
高木的小天才3 小时前
鸿蒙中的并发线程间通信、线程间通信对象
前端·华为·typescript·harmonyos
脑极体7 小时前
开源鸿蒙,给机器人带来了什么?
华为·机器人·开源·harmonyos
HarmonyOS_SDK8 小时前
意图框架事件推荐方案,精准匹配用户需求
harmonyos
Tolitres8 小时前
「鸿蒙 NEXT」基于 taskpool 实现自定义 Timer 工具类
harmonyos
城中的雾9 小时前
一键多环境构建——用 Hvigor 玩转 HarmonyOS Next
harmonyos
别说我什么都不会10 小时前
【仓颉三方库】分布式——config-client
harmonyos
咸鱼过江10 小时前
openharmony5.0.0中C++公共基础类测试-线程相关(一)
c++·harmonyos
我爱鸿蒙开发11 小时前
🥇聊聊鸿蒙的一端开发,多端部署。
前端·开源·harmonyos
智驾14 小时前
HarmonyOS 是 Android 套壳嘛?
android·harmonyos·替代·套壳
悬空八只脚15 小时前
React-Native开发鸿蒙NEXT-svg绘制睡眠质量图part2
harmonyos