组件的状态ComponentV2

介绍

在鸿蒙(HarmonyOS)开发,特别是使用 ArkTS 和 声明式 UI(类似 SwiftUI 或 React)进行开发时,状态管理是核心概念。

要理解"为什么需要状态管理",我们首先需要回到一个更本质的问题:在现代化的声明式 UI 框架中,数据(状态)与界面(UI)是什么关系?

简单来说,状态管理是连接"数据"与"界面"的桥梁。

  • 没有状态管理:你需要手动去"推"数据到界面上,累且易错。
  • 有了状态管理:你只需要维护好数据(状态),界面会自动"拉"取最新的数据并展示自己。

我们可以先写代码感受一下

@Local

@Local表示组件内部的状态,使得自定义组件内部的变量具有观察变化的能力:

这是我们的第一个状态管理装饰器 如果@Local没有装饰变量那么this.text的改变就不会影响到Text()组件

ts 复制代码
@ComponentV2
export struct stateStudy{
  @Consumer('nav')nav:NavPathStack = new NavPathStack()
  @Local text:string = "Hello world"
  build() {
    NavDestination(){
      Text(this.text)
      Button("change")
        .onClick((event: ClickEvent) => {
          this.text = "Hello world changed"
      })
    }
    .title("状态管理")
  }
}
@Param

@Param不仅可以接受组件外部输入,还可以接受@Local的同步变化。

ts 复制代码
@ComponentV2
export struct SonComponent{
  @Param text:string = "default value"
// @Once @Param text:string = "default value"  表示只同步一次 后续父组件的修改将不被同步

  build() {
    Text(this.text)
      .padding(10)
      .backgroundColor(Color.Orange)
  }
}
ts 复制代码
@ComponentV2
export struct stateStudy{
  @Consumer('nav')nav:NavPathStack = new NavPathStack()
  // @Local表示组件内部的状态,使得自定义组件内部的变量具有观察变化的能力:
  @Local text:string = "Hello world"
  build() {
    NavDestination(){
    //   子组件接受夫组件的参数
      SonComponent({text:this.text})
      Button("change")
        .onClick((event: ClickEvent) => {
            // 父组件的text参数被Local装饰 当@Local改变子组件也会同步改变
          this.text = "Hello world changed"
      })
    }
    .title("状态管理")
  }
}
@Event

@Event主要配合@Param实现数据的双向同步。

子组件

ts 复制代码
@ComponentV2
export struct SonComponent{
  @Param text:string = "default value"
  @Event $text:(val:string)=>void = (val:string)=>{}
  build() {
   Column(){
     Text(this.text)
       .padding(10)
       .backgroundColor(Color.Orange)
     Button('son Change').onClick((event: ClickEvent) => {
        // 子组件调用方法传递给父组件
       this.$text("son val")
     })
   }
  }
}

父组件

ts 复制代码
@ComponentV2
export struct stateStudy{
  @Consumer('nav')nav:NavPathStack = new NavPathStack()
  @Local text:string = "Hello world"
  build() {
    NavDestination(){
        // 接受回调函数修改父组件状态变量
      SonComponent({text:this.text,
      $text:(val:string)=>{
        this.text =val
      }})
      Button("change")
        .onClick((event: ClickEvent) => {
          this.text = "Hello world changed"
      })
    }
    .title("状态管理")
  }
}

当然也可以使用语法糖改造优化代码

ts 复制代码
// 原来
SonComponent({
  text: this.text,
  $text: (val: string) => {
    this.text = val;
  },
});
// 修改后
SonComponent({ text: this.text!! });

子组件不变

@Provider和@Consumer

@Provider装饰器和@Consumer装饰器:跨组件层级双向同步

当我们的组件嵌套过多需要很多的param过于繁琐 使用@Provider和@Consumer实现依赖注入

父组件

ts 复制代码
@Provider('nav') nav:NavPathStack = new NavPathStack()

子组件获取 当然也可以是孙组件 间隔多少层都问题不大

ts 复制代码
@Consumer('nav')nav:NavPathStack = new NavPathStack()
相关推荐
ONEDAY1 天前
HarmonyOS 深色模式适配实践:从资源、WebView 到网络图统一处理
harmonyos
鸿蒙开发2 天前
鸿蒙(HarmonyOS NEXT)表单校验别再手撸正则了 —— 我写了个 ArkTS 版 zod
harmonyos
TrisighT2 天前
ArkTS 的 @BuilderParam 你八成只用了皮毛——那个尾随闭包写法差点被我当 bug 删了
harmonyos·arkts·arkui
ONEDAY3 天前
HarmonyOS 多 Product 构建实践:一套代码生成多个产物
harmonyos
TT_Close3 天前
别劝退了!5秒搞定 Flutter 鸿蒙 FVM 起跑线
flutter·harmonyos·visual studio code
TrisighT3 天前
ArkTS 列表滚动时为什么会闪现旧数据?我扒了 LazyForEach 的复用逻辑
harmonyos·arkts·arkui
MonkeyKing3 天前
鸿蒙ArkTS深度剖析:ArkTS与TS/JS核心差异、静态强类型实战优势
typescript·harmonyos
TrisighT3 天前
Electron鸿蒙PC上写日志文件,我被权限和路径坑了两次
electron·harmonyos
TrisighT4 天前
一个下午搞定 ArkTS 折叠面板?结果我从两点写到晚上九点
harmonyos·arkts·arkui
花椒技术7 天前
HJPusher / HJPlayer SDK 实践:我们为什么把直播推播链路拆成一套可复用能力
设计模式·harmonyos·直播