ArkTS 进阶之道(20):@Link 跨组件双向同步边界——父改子同步+子改父同步为啥要 $ 语法

发布时间:2026/11/11 18:47:15

ArkTS 进阶之道(20):@Link 跨组件双向同步边界——父改子同步+子改父同步为啥要 $ 语法 ArkTS 进阶之道20Link 跨组件双向同步边界——父改子同步子改父同步为啥要 $ 语法本文是「ArkTS 进阶之道」系列第 20 篇续「ArkUI 状态联动」深水区篇 68 开篇。上篇讲 Watch 状态监听边界Watch 绑 State 变触发副作用回调槽。本文讲跨组件双向同步边界Link 荬饰器父改子同步子改父同步双向——根因在 $ 语法双向绑定不是单向传值Link 父改子同步子改父同步双向Prop 父改子同步单向子改父不同步。能力系列篇 20 讲过 Link 怎么用本文讲为哈 Link 双向同步合法 Prop 单向同步子改父不同步——根因在 $ 语法双向绑定。一、开篇Link 不是单向传值是 $ 语法双向绑定的跨组件同步你写 React 时父子组件状态同步是「回调魔法」父传 props 子改父调回调// React 父子组件状态同步父传 props 子改父调回调 function Parent() { const [count, setCount] useState(0) return Child count{count} onCountChange{setCount} / // 父传 props 回调 } function Child({ count, onCountChange }) { return button onClick{() onCountChange(count 1)}子改 count{count}/button } // React 父子同步父传 props 子改父调回调回调魔法你写鸿蒙 ArkTS 时Link$ 语法双向绑定——父改子同步子改父同步双向// ArkTS Link $ 语法双向绑定 Entry Component struct Index { State linkCount: number 0 // ✅ 父 State linkCount build() { Column() { ChildLink({ childCount: $linkCount }) // ✅ $ 语法双向绑定父改子同步子改父同步 } } } Component struct ChildLink { Link childCount: number // ✅ Link 子 childCount 双向同步父 State linkCount build() { Button(子改 childCount${this.childCount}) .onClick(() { this.childCount }) // ✅ 子改 childCount → 父 State linkCount 同步 } } // Link $ 语法双向绑定父改子同步子改父同步双向回调魔法 vs $ 语法双向绑定的区别React 把父子同步当回调魔法父传 props 子改父调回调ArkTS 把 Link 当「$ 语法双向绑定荬饰器」父改子同步子改父同步双向。根因不是回调魔法是 $ 语法双向绑定——Link $ 语法编译期绑父子双向同步槽父改子同步子改父同步双向。二、根因Link 的 $ 语法双向绑定机制鸿蒙 ArkUI 的 Link 是**$ 语法双向绑定**——编译期把 Link 绑成父子双向同步槽父改子同步子改父同步双向来自三重绑定机制。机制 1Link $ 语法编译期绑父子双向同步槽——不是单向传值Link 荬饰器 $ 语法编译期绑父子双向同步槽——把 $linkCount 绑成父子双向同步槽父改子同步子改父同步双向Entry Component struct Index { State linkCount: number 0 // ✅ 父 State linkCount build() { Column() { ChildLink({ childCount: $linkCount }) // ✅ $ 语法双向绑定编译期绑父子双向同步槽 } } } Component struct ChildLink { Link childCount: number // ✅ Link 子 childCount 双向同步父 State linkCount build() { Column() { Text(childCount ${this.childCount}) Button(子改 childCountLink 子改父同步) .onClick(() { this.childCount }) // ✅ 子改 childCount → 父 State linkCount 同步 } } } // 编译期$linkCount 绑成父子双向同步槽父 State linkCount ↔ 子 Link childCount // 运行时父改 linkCount → 子 childCount 同步 子改 childCount → 父 linkCount 同步双向编译期绑父子双向同步槽Link $ 语法编译期把$linkCount绑成父子双向同步槽——父State linkCount↔ 子Link childCount双向同步。父改linkCount→ 子childCount同步子改childCount→ 父linkCount同步双向。根因不是单向传值是 $ 语法双向绑定。机制 2Prop 单向同步——父改子同步子改父不同步无 $ 语法Prop 荬饰器单向同步——父改子同步子改父不同步无 $ 语法子只改本地副本Entry Component struct Index { State propCount: number 0 // ⚠ 父 State propCount build() { Column() { ChildProp({ childCount: this.propCount }) // ⚠ Prop 单向同步无 $ 语法传值副本 } } } Component struct ChildProp { Prop childCount: number // ⚠ Prop 单向同步父改 childCount 子同步 子改 childCount 父不同步 build() { Column() { Text(childCount ${this.childCount}) Button(子改 childCountProp 子改父不同步) .onClick(() { this.childCount }) // ⚠ Prop 子改 childCount → 父 State childCount 不同步只改子本地副本 } } } // Prop 单向同步父改 propCount → 子 childCount 同步 子改 childCount → 父 propCount 不同步只改子本地副本Prop 单向同步Prop 无 $ 语法单向同步——父改propCount→ 子childCount同步子改childCount→ 父propCount不同步只改子本地副本。根因不是双向同步是单向传值副本——Prop 子只改本地副本不回传父。机制 3Link $ 语法 vs Prop 传值边界——双向同步 vs 单向传值Link$ 语法双向同步父改子同步子改父同步双向Prop传值单向同步父改子同步子改父不同步单向——根因都是父子同步但绑的机制不同Entry Component struct Index { State linkCount: number 0 // ✅ Link 父状态父改子同步 子改父同步双向 State propCount: number 0 // ⚠ Prop 父状态父改子同步单向子改父不同步 build() { Column() { // ✅ Link 路径$ 语法双向绑定父改子同步子改父同步双向 ChildLink({ childCount: $linkCount }) // ⚠ Prop 路径传值单向同步父改子同步子改父不同步单向 ChildProp({ childCount: this.propCount }) } } } // Link $ 语法双向绑定父改 linkCount → 子 childCount 同步 子改 childCount → 父 linkCount 同步双向 // Prop 传值单向同步父改 propCount → 子 childCount 同步 子改 childCount → 父 propCount 不同步单向Link $ 语法 vs Prop 传值边界Link 路径——$ 语法双向绑定父改子同步子改父同步双向推荐。Prop 路径——传值单向同步父改子同步子改父不同步单向子改只改本地副本。根因都是父子同步但绑的机制不同——Link $ 语法双向绑定双向同步槽Prop 传值单向同步单向传值副本。机制 4Link $ 语法必须配 State——不能配普通变量Link$ 语法必须配 State——$ 语法双向绑定要求父状态是 State响应式不能配普通变量Entry Component struct Index { State linkCount: number 0 // ✅ State 配 Link $ 语法双向绑定 private normalCount: number 0 // ❌ 普通变量不能配 Link $ 语法无响应式 build() { Column() { // ✅ Link $ 语法配 State双向同步合法 ChildLink({ childCount: $linkCount }) // ❌ Link $ 语法配普通变量编译报错$ 语法要求 State 响应式 // ChildLink({ childCount: $normalCount }) // ❌ 编译报错 } } } // Link $ 语法必须配 State$ 语法双向绑定要求父状态是 State响应式 // 普通变量无响应式不能配 Link $ 语法编译报错Link $ 语法必须配 StateLink $ 语法双向绑定要求父状态是 State响应式普通变量无响应式不能配 Link $ 语法编译报错。根因不是任意变量是 State 响应式——Link $ 语法双向同步槽要求父 State 响应式才能双向同步。三、真机配图Link 跨组件双向同步边界——$ 语法双向绑定初始态父 linkCount0、父 propCount0、两子组件 childCount0 均双向同步边界初始值点调四按钮后父 linkCount1 子 ChildLink childCount1 父子都同步、父 propCount1 子 ChildProp childCount1 父同步但子改后父 propCount 仍1 不同步均双向同步边界对比证据齐对比证据点父改 linkCount 后子 ChildLink childCount 同步父改子同步点子改 ChildLink childCount 后父 linkCount 同步子改父同步双向。点父改 propCount 后子 ChildProp childCount 同步父改子同步点子改 ChildProp childCount 后父 propCount 仍1 不同步子改父不同步单向。Link $ 语法双向绑定父改子同步子改父同步双向vs Prop 传值单向同步父改子同步子改父不同步单向——Link 荬饰器 $ 语法编译期绑父子双向同步槽Prop 传值单向同步子改只改本地副本。四、真解法Link 跨组件双向同步的三个场景场景 1Link 父子计数器双向同步90% 场景首选$ 语法双向绑定Entry Component struct Index { State count: number 0 // ✅ 父 State count build() { Column() { Text(父 count ${this.count}) ChildCounter({ childCount: $count }) // ✅ $ 语法双向绑定 } } } Component struct ChildCounter { Link childCount: number // ✅ Link 子 childCount 双向同步父 State count build() { Column() { Text(子 childCount ${this.childCount}) Button(子改 childCount) .onClick(() { this.childCount }) // ✅ 子改 childCount → 父 State count 同步 } } }为哈能跑Link 父子计数器双向同步——$ 语法双向绑定父改 count → 子 childCount 同步 子改 childCount → 父 count 同步双向。首选这个90% 的场景父子组件状态双向同步用 Link $ 语法双向绑定就够。要写「父子组件状态双向同步计数器等」时用这个——不用 Prop 单向同步子改父不同步Link $ 语法双向绑定父子都同步。场景 2Link 父子表单双向同步$ 语法双向绑定子改父同步Entry Component struct Index { State name: string // ✅ 父 State name build() { Column() { Text(父 name ${this.name}) ChildInput({ childName: $name }) // ✅ $ 语法双向绑定 } } } Component struct ChildInput { Link childName: string // ✅ Link 子 childName 双向同步父 State name build() { TextInput({ text: this.childName, placeholder: 输入姓名 }) .onChange((value: string) { this.childName value }) // ✅ 子改 childName → 父 State name 同步 } } // Link 父子表单双向同步子 Input 改 childName → 父 State name 同步子改父同步双向 // 不用 Prop 单向同步子改父不同步Link $ 语法双向绑定父子都同步为哈能跑Link 父子表单双向同步——$ 语法双向绑定子 Input 改childName→ 父State name同步子改父同步双向。要写「父子表单双向同步Input 改子父同步等」时用这个——不用 Prop 单向同步子改父不同步Link $ 语法双向绑定父子都同步。场景 3Link 父子对象双向同步$ 语法双向绑定对象引用同步interface User { name: string; age: number } Entry Component struct Index { State user: User { name: 张三, age: 25 } // ✅ 父 State user 对象 build() { Column() { Text(父 user ${JSON.stringify(this.user)}) ChildUser({ childUser: $user }) // ✅ $ 语法双向绑定对象 } } } Component struct ChildUser { Link childUser: User // ✅ Link 子 childUser 双向同步父 State user 对象 build() { Column() { TextInput({ text: this.childUser.name, placeholder: 姓名 }) .onChange((value: string) { this.childUser.name value }) // ✅ 子改 childUser.name → 父 State user.name 同步 Button(子改 age) .onClick(() { this.childUser.age }) // ✅ 子改 childUser.age → 父 State user.age 同步 } } } // Link 父子对象双向同步$ 语法双向绑定对象引用子改 childUser.name/age → 父 State user.name/age 同步双向 // 对象引用同步Link 绑对象引用子改对象属性父同步不用深拷贝为哈能跑Link 父子对象双向同步——$ 语法双向绑定对象引用子改childUser.name/age→ 父State user.name/age同步双向。要写「父子对象双向同步对象属性改父子都同步等」时用这个——不用 Prop 单向同步子改对象属性父不同步Link $ 语法双向绑定对象引用父子都同步。五、一句话哲学Link 不是单向传值是 $ 语法双向绑定的跨组件同步。ArkUI 的 Link 荬饰器 $ 语法编译期绑父子双向同步槽父改子同步子改父同步双向。根因不是单向传值是 $ 语法双向绑定——Link $ 语法编译期绑父子双向同步槽父 State ↔ 子 Link 双向同步 Prop 传值单向同步父改子同步子改父不同步子改只改本地副本 Link $ 语法必须配 State$ 语法双向绑定要求父 State 响应式 Link $ 语法 vs Prop 传值边界双向同步 vs 单向传值。对比 React 父子组件状态同步回调魔法父传 props 子改父调回调ArkTS Link $ 语法双向绑定父子都同步。状态联动深水区串讲Watch 绑 State 变触发副作用回调槽篇 68onClick 改 State 不直接调副作用单向数据流 Link $ 语法双向绑定跨组件同步篇 69父改子同步子改父同步双向——续「ArkUI 状态联动」深水区讲状态联动深水区Watch 副作用回调槽边界 Link $ 语法双向绑定边界。系列预告下篇篇 70讲 Provide/Consume 跨层级传递边界祖辈 Provide 后辈 Consume 跨层级传递根因续「ArkUI 状态联动」深水区。五阶段哲学体系类型哲学50-52→ 作用域哲学53-55→ 状态哲学56-59→ 渎染哲学60-62→ 组件设计63-67→ 状态联动深水区68讲清 ArkTS/ArkUI 进阶哲学。能力系列回链能力系列篇本文进阶点篇 20 Link 用法Link $ 语法双向绑定边界根因父改子同步子改父同步双向篇 13 State 基础用法状态哲学State 赋值就刷 UI 依赖追踪篇 59 Watch 用法状态联动深水区Watch 副作用回调槽 vs onClick 直接调副作用边界真机 demo 完整代码// 篇 69 demoLink 跨组件双向同步边界——父改子同步 子改父同步双向 // 对比Link 双向同步父改子子改父都同步vs Prop 单向同步父改子同步子改父不同步 // ✅ 子组件Link 双向同步——父改子同步 子改父同步 Component struct ChildLink { Link childCount: number // ✅ Link 双向同步父改 childCount 子同步 子改 childCount 父同步 build() { Column({ space: 8 }) { Text(子组件 ChildLinkLink 双向同步) .fontSize(13).fontColor(#2563eb).fontWeight(FontWeight.Bold) Text(childCount ${this.childCount}) .fontSize(16).fontWeight(FontWeight.Bold) Button(子改 childCountLink 子改父同步) .width(92%).height(40).fontSize(12) .onClick(() { this.childCount // ✅ Link 子改 childCount → 父 State childCount 同步 }) } .width(92%).padding(10).backgroundColor(#e0f0ff).borderRadius(8) } } // ⚠ 对比组件Prop 单向同步——父改子同步 子改父不同步Prop 子改不回传父 Component struct ChildProp { Prop childCount: number // ⚠ Prop 单向同步父改 childCount 子同步 子改 childCount 父不同步 build() { Column({ space: 8 }) { Text(对比组件 ChildPropProp 单向同步) .fontSize(13).fontColor(#ff6600).fontWeight(FontWeight.Bold) Text(childCount ${this.childCount}) .fontSize(16).fontWeight(FontWeight.Bold) Button(子改 childCountProp 子改父不同步) .width(92%).height(40).fontSize(12) .onClick(() { this.childCount // ⚠ Prop 子改 childCount → 父 State childCount 不同步只改子本地副本 }) } .width(92%).padding(10).backgroundColor(#fff0e0).borderRadius(8) } } Entry Component struct Index { State linkCount: number 0 // ✅ Link 父状态父改子同步 子改父同步双向 State propCount: number 0 // ⚠ Prop 父状态父改子同步单向子改父不同步 State log: string (未操作) build() { Column({ space: 12 }) { Text(篇 69 配图Link 跨组件双向同步边界) .fontSize(18).fontWeight(FontWeight.Bold).margin({ top: 20, bottom: 8 }) Text(Link 双向同步父改子子改父都同步vs Prop 单向同步父改子同步子改父不同步) .fontSize(11).fontColor(#888).margin({ bottom: 12 }) // ✅ Link 路径父改 linkCount → 子 Link 同步 子改 childCount → 父 State 同步 Column({ space: 6 }) { Text(父 linkCount ${this.linkCount}).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#2563eb) Button(父改 linkCountLink 父改子同步) .width(92%).height(40).fontSize(12) .onClick(() { this.linkCount // ✅ Link 父改 linkCount → 子 Link childCount 同步 this.log 父改 linkCount${this.linkCount}Link 父改子同步 }) ChildLink({ childCount: $linkCount }) // ✅ Link $ 语法双向绑定 } .width(92%).padding(10).backgroundColor(#f5f5f5).borderRadius(8) // ⚠ Prop 路径父改 propCount → 子 Prop 同步 子改 childCount → 父 State 不同步 Column({ space: 6 }) { Text(父 propCount ${this.propCount}).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#ff6600) Button(父改 propCountProp 父改子同步) .width(92%).height(40).fontSize(12) .onClick(() { this.propCount // ✅ Prop 父改 propCount → 子 Prop childCount 同步 this.log 父改 propCount${this.propCount}Prop 父改子同步 }) ChildProp({ childCount: this.propCount }) // ⚠ Prop 单向同步无 $ 语法 } .width(92%).padding(10).backgroundColor(#f5f5f5).borderRadius(8) Text(日志${this.log}).fontSize(11).fontColor(#333).margin({ top: 4 }) } .width(100%).height(100%).alignItems(HorizontalAlign.Center) } }写鸿蒙 ArkUI 记住Link 不是单向传值是 $ 语法双向绑定的跨组件同步——Link 荬饰器 $ 语法编译期绑父子双向同步槽父改子同步子改父同步双向。根因不是单向传值是 $ 语法双向绑定——Link $ 语法编译期绑父子双向同步槽父 State ↔ 子 Link 双向同步 Prop 传值单向同步父改子同步子改父不同步子改只改本地副本 Link $ 语法必须配 State$ 语法双向绑定要求父 State 响应式 Link $ 语法 vs Prop 传值边界双向同步 vs 单向传值。Link 父子计数器双向同步用 $ 语法双向绑定首选90% 场景Link 父子表单双向同步用 $ 语法双向绑定子改父同步Link 父子对象双向同步用 $ 语法双向绑定对象引用同步。$ 语法双向绑定父子都同步是 ArkUI 状态联动深水区核心
延伸阅读

更多相关文章

2026/11/11 5:47:54

Modbus RTU协议详解:从原理到实战的工业通信指南

1. 项目概述:从工业现场到数字世界的桥梁在工业自动化、楼宇自控、能源管理这些领域里,我们常常需要让一堆“哑巴”设备开口说话,把温度、压力、开关状态这些物理信号,变成计算机能理解、能处理的数据。这个“翻译”工作&#xff…

2026/11/11 11:28:22

五子棋游戏开发:从设计到实现的全流程解析

1. 五子棋系统设计概述五子棋作为一款经典的双人策略型棋类游戏,其电子化实现涉及多个技术模块的协同工作。这个设计报告完整呈现了从需求分析到最终实现的完整开发流程,包含可运行的源码、详细设计文档和配套讲解资料。整套方案不仅实现了基础的对弈功能…

2026/11/11 18:46:04

新疆电工证图片值不值得考?学历不高怕报不上名?真相来了!

新疆电工证图片值不值得考?学历不高怕报不上名?真相来了! 你是不是也觉得,自己学历不高,担心报名不了新疆电工证?别急,听我跟你唠唠。今天咱们就聊聊 新疆电工证图片 到底值不值得考,以及那些你可能不知道的报考避坑干货。先说重点:…

2026/11/11 18:46:04

电工证几大项目千万别踩坑,怕考不过白交培训费

电工证几大项目千万别踩坑,怕考不过白交培训费 你是不是也遇到过这样的情况:报了一个电工证培训班,花了几千块,结果考试没过,培训费打水漂? 千万别踩坑 ,这是很多学员在办理电工证过程中最容易犯的错误。今天我们就来聊聊 电工证几大项目…

2026/11/11 18:46:04

邵东劳务市场电工证通过率揭秘:别让培训费打水漂

邵东劳务市场电工证通过率揭秘:别让培训费打水漂 怕考不过白交培训费?你不是一个人。我见过太多人报名参加邵东劳务市场电工证考试,最后因为没通过,钱花了、时间搭了,还影响了项目进度。今天就来聊聊这背后的通过率真相,以及怎么才能不被坑。…

2026/11/11 18:46:04

河池电工证年审怎么网上查询?别被中介坑了

河池电工证年审怎么网上查询?别被中介坑了 你是不是也遇到过这种情况:听说要年审电工证,上网一查信息五花八门,不知道该去哪报名,生怕被中间人坑了钱还办不成?别急,今天咱们就用一个真实的案例,讲讲 河池电工证年审 到底怎么搞,还教你怎么…

2026/11/11 18:41:04

40岁能办电工证吗考前押题全攻略

40岁能办电工证吗考前押题全攻略 你是不是也担心40岁了还能不能办电工证?怕被中介忽悠,不知道去哪报名?别急,这篇文章给你讲透!不仅告诉你40岁能不能办电工证,还有考前押题怎么准备、哪里报名最靠谱,全都是实打实的干货。…

2026/11/11 12:42:59

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/11 0:02:26

考低压电工证通过率考试真题与备考技巧

低压电工证通过率高不高?学历不高也能考,值不值得考? 你是不是总听说电工证能帮你找高薪工作,但又担心自己学历不够,考不上?其实,低压电工证考试门槛并没有你想象中那么高,关键是方法对不对。这篇文章就告诉你, 考低压电工证通过率到底有多高 ,…

2026/11/11 0:02:26

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名 你是不是也和我一样,刚毕业就听说低压电工证学时必须达标才能上岗?可一打听,发现报名机构五花八门,价格参差不齐, 不知道去哪报名怕被中介坑…

2026/11/10 20:08:15

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑