鸿蒙 ArkTS 状态管理:@State/@Prop/@Link 三层传递的实战取舍

举报
yd_239489350 发表于 2026/11/11 02:18:34 2026/11/11
【摘要】 写鸿蒙页面时,常遇到数据改了界面不动,或子组件一改父组件也被改动。问题多半出在状态装饰器用错了地方。@State、@Prop、@Link 都能传数据,但分工不同,本文用待办清单讲清它们的取舍。 一、三者分工记住一句话:@State 管自己,@Prop 只读父组件传下来的值,@Link 和父组件共享同一份数据。父组件改了,@Prop 和 @Link 的子组件都会变;子组件改了,只有 @Link...

写鸿蒙页面时,常遇到数据改了界面不动,或子组件一改父组件也被改动。问题多半出在状态装饰器用错了地方。@State、@Prop、@Link 都能传数据,但分工不同,本文用待办清单讲清它们的取舍。

一、三者分工

记住一句话:@State 管自己,@Prop 只读父组件传下来的值,@Link 和父组件共享同一份数据。父组件改了,@Prop 和 @Link 的子组件都会变;子组件改了,只有 @Link 能同步回父组件。

二、@State:组件自己的状态

@State 是组件自己的状态,值一变就刷新界面。计数、输入文字、开关状态都适合用它。

@State count: number = 0;
Button('加一').onClick(() => { this.count++; })

count 只在当前组件用,不用经过父子传递。

三、@Prop:单向的“只读副本”

@Prop 接收父组件的数据,是单向副本:父改子变,子改父不变,适合只展示的列表项和标题栏。不要在子组件里改 @Prop 回传结果,下次父组件同步会把它覆盖掉。

@Prop done: boolean = false;
Text(this.done ? '已完成' : '待完成')

四、@Link:双向的“共享引用”

@Link 和父组件共享同一份数据,任何一端改动都会同步。勾选框、开关这类子组件要改、父组件也要知道的场景用它。父组件传值要加 $ 号:TodoItem({ done: $done })。

@Link done: boolean;
Checkbox({ checked: this.done })
  .onChange((v: boolean) => { this.done = v; })

五、实战取舍:待办清单怎么选

待办清单页:页面用 @State 维护 todos 数组;列表项只展示时用 @Prop,有勾选框要回写统计时用 @Link。原则是能单向就别双向:先搭 @State 加 @Prop 的单向数据流,确实需要回写时,再把那一个字段升级为 @Link。

六、三个常见坑

一,子组件改 @Prop 父组件没变是正常现象,该用 @Link。二,@Link 漏了 $ 号就退化成普通传值。三,状态不要层层透传,超过两层还靠 @Prop 接力,就该把状态上提到共同父组件。

结语

三者是一条从自己管到父子共享的递进链路:先分清数据归谁,再决定同步方向,状态就不会乱。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。