MoodSelector 心情组件:@Link 双向绑定实现父子通信

发布时间:2026/7/19 21:54:24
MoodSelector 心情组件:@Link 双向绑定实现父子通信 前言在“海风日记“的写日记功能中心情选择器是核心交互组件之一。用户可以从 5 种心情和 5 种天气中选择选择结果会实时反映在 UI 上。MoodSelector组件通过Link装饰器实现与父组件的双向绑定子组件修改选择项后父组件的状态自动更新。本文将从源码出发深入讲解 Link 的完整用法。一、Link 双向绑定1.1 子组件定义Component export struct MoodSelector { Link selectedMood: number // 双向绑定心情 Link selectedWeather: number // 双向绑定天气 build() { Column() { // 心情选项 ForEach(MOOD_OPTIONS, (item, index) { Text(item.emoji) .onClick(() { this.selectedMood index }) }) // 天气选项 ForEach(WEATHER_OPTIONS, (item, index) { Text(item.emoji) .onClick(() { this.selectedWeather index }) }) } } }1.2 父组件使用Entry Component struct WriteDiaryPage { State selectedMood: number 3 // 默认开心 State selectedWeather: number 0 // 默认晴天 build() { MoodSelector({ selectedMood: this.selectedMood, // 传入 State selectedWeather: this.selectedWeather // 传入 State }) } }二、心情选项配置2.1 数据定义const MOOD_OPTIONS: MoodOption[] [ { emoji: , label: 难过 }, { emoji: , label: 低落 }, { emoji: , label: 平静 }, { emoji: , label: 还不错 }, { emoji: , label: 开心 }, ] const WEATHER_OPTIONS: WeatherOption[] [ { emoji: ☀️, label: 晴 }, { emoji: ⛅, label: 多云 }, { emoji: ️, label: 雨 }, { emoji: ️, label: 大风 }, { emoji: ❄️, label: 雪 }, ]2.2 心情选择 UIRow({ space: 8 }) { ForEach(MOOD_OPTIONS, (item: MoodOption, index: number) { Column({ space: 4 }) { Text(item.emoji) .fontSize(20) .width(40).height(40).textAlign(TextAlign.Center) .borderRadius(20) .backgroundColor( this.selectedMood index ? rgba(255,255,255,0.90) : rgba(255,255,255,0.55) ) .border({ width: this.selectedMood index ? 1.5 : 0, color: rgba(245,166,35,0.5) }) .shadow(this.selectedMood index ? { radius: 8, color: rgba(245,166,35,0.25) } : { radius: 0, color: transparent } ) Text(item.label) .fontSize(9.5) .fontColor(this.selectedMood index ? #D4900A : COLOR_TEXT_HINT) .fontWeight(this.selectedMood index ? FontWeight.Bold : FontWeight.Normal) } .onClick(() { this.selectedMood index }) }) }三、State 与 Link 的对比3.1 装饰器对比装饰器数据流向声明位置修改权限State内部状态组件内部仅本组件Prop父→子单向子组件不可同步回父组件Link双向绑定子组件可同步回父组件3.2 选择指南子组件需要修改父组件数据 → 使用Link子组件只展示父组件数据 → 使用Prop或普通属性数据只在组件内部使用→ 使用State四、天气选择 UIRow({ space: 8 }) { ForEach(WEATHER_OPTIONS, (item: WeatherOption, index: number) { Row({ space: 4 }) { Text(item.emoji).fontSize(12) Text(item.label).fontSize(12) .fontColor(this.selectedWeather index ? #C8800A : COLOR_AMBER) .fontWeight(this.selectedWeather index ? FontWeight.Bold : FontWeight.Normal) } .padding({ left: 10, right: 10, top: 5, bottom: 5 }) .borderRadius(14) .backgroundColor( this.selectedWeather index ? rgba(255,255,255,0.85) : rgba(255,255,255,0.45) ) .border({ width: 1, color: this.selectedWeather index ? rgba(245,166,35,0.35) : rgba(245,166,35,0.15) }) .onClick(() { this.selectedWeather index }) }) }五、完整组件布局Column({ space: 0 }) { // 心情选择 Text(今天的心情) .fontSize(11).fontColor(COLOR_AMBER).fontWeight(FontWeight.Medium) .margin({ bottom: 8 }) // 心情 Row this.moodRow() // 天气 Row this.weatherRow() } .width(100%) .alignItems(HorizontalAlign.Start)六、常见问题与排查6.1 Link 绑定失败问题子组件修改了Link变量但父组件 UI 没有更新。原因父组件传入的值不是State变量。解决方案确保父组件传入的是State变量。6.2 选中态不显示问题点击心情选项后选中状态没有变化。原因Link绑定成功但 UI 判断逻辑有误。解决方案检查selectedMood index的比较逻辑。总结本文通过“海风日记“的 MoodSelector 组件深入讲解了 Link 双向绑定的用法Link 装饰器子组件中定义与父组件 State 双向绑定心情选项5 种心情的 emoji 和标签天气选项5 种天气的 emoji 和标签选中态样式背景色、边框、阴影的条件切换State vs Link不同装饰器的选择策略下一篇文章将深入讲解TextInput 与 TextArea输入框的优化体验敬请期待。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源Link 装饰器文档State 装饰器文档Prop 装饰器文档海风日记项目源码[HarmonyOS 开发者官网](https://atomgit.com/openharmony/docs开源鸿蒙跨平台社区