鸿蒙 ArkTS 状态管理:@State/@Prop/@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 接力,就该把状态上提到共同父组件。
结语
三者是一条从自己管到父子共享的递进链路:先分清数据归谁,再决定同步方向,状态就不会乱。
- 点赞
- 收藏
- 关注作者
评论(0)