ArkUI实战演练04-状态管理与数据驱动

ArkUI实战演练04-状态管理与数据驱动

小伙伴们,上次做商城项目的时候,被状态管理坑惨了------子组件里改了数据,父组件纹丝不动,折腾了半天才发现是@Prop和@Link没用对。今天就来聊聊ArkUI的状态管理与数据驱动,把几个装饰器捋清楚,下次别再踩这个坑了。

核心概念

ArkUI的状态管理基于装饰器机制。组件内部用@State定义本地状态,父子组件间通过@Prop@Link实现单向/双向数据传递,@Watch用来监听状态变化。这些装饰器都必须在ArkTS里声明才能用。

环境准备

  • DevEco Studio 6.1.0 及以上
  • HarmonyOS SDK 6.1.0(23) 及以上

建议用最新的DevEco Studio,不然有些特性不支持------别问我是怎么知道的,上次就因为版本低了,@Watch死活不生效,差点重装系统。

核心实现

1. 使用@State定义组件本地状态

先上代码,看看最简单的用法:

typescript 复制代码
@Entry
@Component
struct MyComponent {
  @State count: number = 0;

  build() {
    Column() {
      Text(`Count: ${this.count}`)
      Button('Increment')
        .onClick(() => {
          this.count++;
        })
    }
  }
}

@State装饰的变量一变,UI就自动刷新。这个机制用起来挺爽的,不过要记住:@State只对基本类型和类对象有效,你要是直接push数组元素,它可不会刷新UI,得用扩展运算符或者this.arr = [...this.arr, newItem]才行。

2. 父子组件数据传递:@Prop(单向)

父组件把数据传给子组件,子组件只能读不能写,这点坑了我好久。贴一下核心代码:

typescript 复制代码
@Component
struct Child {
  @Prop value: number;

  build() {
    Text(`Child: ${this.value}`)
  }
}

@Entry
@Component
struct Parent {
  @State parentValue: number = 10;

  build() {
    Column() {
      Child({ value: this.parentValue })
    }
  }
}

@Prop是只读的,子组件里想改?没门!只能靠父组件去改。所以设计数据流的时候要想清楚谁拥有数据,不然子组件里偷偷改了,父组件还不知道,界面就不一致了。我习惯把这种单向传递用在展示型子组件上,比如商品卡片,只管显示,别乱动。

3. 父子组件数据同步:@Link(双向)

想要子组件改了数据,父组件也跟着变?那就用@Link,注意传参要用$符号。直接上代码:

typescript 复制代码
@Component
struct Child {
  @Link value: number;

  build() {
    Button('Add One')
      .onClick(() => {
        this.value++;
      })
  }
}

@Entry
@Component
struct Parent {
  @State count: number = 0;

  build() {
    Column() {
      Child({ value: $count })
    }
  }
}

注意这里传的是$count而不是count------这个设计挺奇怪的,我第一次写漏了$,结果子组件怎么点都不变,控制台也没报错,找了半天才发现是语法问题。习惯了就好,记住:@Link必须用美元符号传递引用。

4. 监听状态变化:@Watch

有时候状态变了需要触发一些额外逻辑,比如保存到本地或者打印日志。这时候@Watch就派上用场了。贴一下代码:

typescript 复制代码
@Entry
@Component
struct WatcherDemo {
  @State @Watch('onCountChange') count: number = 0;

  onCountChange() {
    console.info(`Count changed to ${this.count}`);
  }

  build() {
    Button('Change')
      .onClick(() => {
        this.count++;
      })
  }
}

被@Watch装饰的变量一变化,就自动执行指定方法。这个回调是同步执行的,所以千万别在里面做网络请求或者大循环,会卡住UI的。我通常用它来配合本地存储,状态变了就同步写入数据库。

注意事项

有几个坑我得提醒大家:

  • @Prop修饰的变量在子组件里是只读的,强行修改会触发警告,但数据不会同步回父组件。我之前试过在子组件里this.value++,结果父组件纹丝不动,UI也乱套了。
  • @Link必须用$语法传递引用(比如$count),不能直接传值。传值的话子组件拿到的就是个副本,改了也没用。
  • @Watch回调函数在状态变量变化时同步执行,应避免在其中进行耗时操作,否则会出现界面卡顿的错觉。
  • 嵌套装饰器使用(比如@State@Watch同时修饰)时,注意执行顺序------先触发状态变化,再调用@Watch回调。有时候多个状态关联变化,@Watch可能会被连续触发,要做好去重或者防抖。

常见问题FAQ

Q: @Prop和@Link有什么区别?

A: @Prop是单向数据流,子组件只能读,不能改父组件的数据;@Link是双向同步,子组件里改了,父组件也会跟着变。很多新手问我这个,你就记住:单向用@Prop,双向用@Link,传参别忘了加$。

Q: @Watch能和其他装饰器一起用吗?

A: 可以。@State @Watch('method') variable是常见写法,监听该变量的变化。不过要注意,如果@Watch和@Prop一起用,只能在父组件里写,子组件上的@Prop变量没法加@Watch(文档没明确说,但我试过会报错)。

好啦,今天就到这,有问题欢迎评论区交流,觉得有用点个赞哦~

上次做项目时,就因为 @State@Watch 同时用没注意顺序,数据死活不同步,排查了俩小时才发现是执行次序的坑。与 @Watch 同时修饰)需注意执行顺序。

常见问题FAQ

Q: @Prop和@Link有什么区别?

A: 单向数据流 vs 双向同步------简单说,@Prop 子组件只能读不能改父组件数据,@Link 子组件改了父组件也跟着变。我个人建议哈,如果只是展示数据用 @Prop 就够,需要子组件修改父组件数据(比如编辑弹窗)就用 @Link,少走弯路!

Q: @Watch能和其他装饰器一起用吗?

A: 可以,很常用!比如 @State @Watch('onCountChange') count: number = 0,这样每次 count 变化都会触发 onCountChange 方法。不过提醒一句:@Watch 方法里别做太耗时的操作,否则会卡 UI 的,亲测踩过坑。

Q: 为什么@Link必须用$符号?

A: 这个 是 ArkTS 专门用来生成状态变量"引用包装"的语法糖,说白了就是让父子组件共享同一份数据内存。没有 符号,@Link 就没法实现双向同步。一开始我也觉得这符号挺突兀,用多了发现挺合理的,能一眼看出哪个变量是双向绑定的。


上一篇介绍了《ArkUI实战演练03-布局容器与组件化》中 Flex、Column、Row、Stack 等布局的实践。下一篇将讲解《ArkUI实战演练05-动画与手势交互》,覆盖转场动画、属性动画及手势绑定等内容。

本文内容严格基于 HarmonyOS 官方 ArkUI 文档,所有 API 和示例均提取自文档中明确列出的能力。

小伙伴们如果还有其他装饰器使用问题,欢迎评论区留言交流~觉得这篇文章对你有帮助的话,点个赞再走吧!

相关推荐
坚果的博客15 小时前
AtomCode 助力开源鸿蒙跨平台三方库生态共建
华为·开源·harmonyos
枫叶丹415 小时前
【HarmonyOS 6.0】Live View Kit深度解析:实况胶囊尾部图标的设计哲学与实现全流程
开发语言·华为·harmonyos
小雨青年1 天前
鸿蒙 HarmonyOS 6 | Pura X Max 鸿蒙原生适配 13:顶部导航在窄窗口下如何简化
华为·harmonyos
FrameNotWork1 天前
HarmonyOS 短视频滑动交互实现:打造流畅的上下切换体验
音视频·交互·harmonyos
FrameNotWork1 天前
HarmonyOS 照片浏览器手势交互实现:打造流畅的滑动体验
华为·交互·harmonyos
大雷神1 天前
第03篇|源码导览:从源码看地图、相机、相册、保险箱的产品闭环
harmonyos
花先锋队长1 天前
突破物理极限,华为Pura X Max重新定义折叠机音质天花板
华为·harmonyos
wordbaby1 天前
鸿蒙 RNOH 下 DocumentPicker copyTo 失败:一个错误码,三个独立根因
harmonyos
FrameNotWork1 天前
HarmonyOS 智感握姿开发指南:让 UI 跟着握姿自动换边
ui·华为·harmonyos