华为快应用-父子组件的通信(子传父)

本文介绍华为快应用中子组件如何向父组件传递参数。通过子组件的$dispatch方法触发父组件中定义的事件处理器evtTypeHandler,实现数据的向上层传递。

华为快应用-父子组件的通信(父传子)这篇博客我们知道了父组件是怎么把值传递给子组件的,那么子组件怎么传递值给父组件呢?

//父组件中
        onShow: function() {
        //和父组件向子组件中传值一样,反着传值需要在父组件中绑定事件
            this.$on('evtType2', this.evtTypeHandler)

        },
        //被触发后调用此方法
        evtTypeHandler(evt) {
            console.info('父组件:事件响应: ', evt.type, evt.detail)
            // 结束事件传递
            // evt.stop()
        }

//子组件中
        //通过按钮之类的条件触发
        changeAction() {
            //通过此方法向上传递参数,即可调用父组件中evtTypeHandler方法
            this.$dispatch('evtType2', { params: '向上传递的参数' })
        },

以上,学到就是赚到,可以节省很多功夫的,觉得有用,不妨给个评论鼓励吧。

<think>我们正在讨论鸿蒙系统中组件通信的V1和V2版本(即状态管理的两个版本)的区别及实现方式。根据引用[1]的内容,我们可以总结出以下几点: 1. **组件混用规则**: - V1自定义组件中不能使用V2装饰器,否则编译报错。 - 当组件间没有变量递时,V1组件可以使用V2组件(包括第三方V2组件)。 - 当组件间有变量递时: - V1递给V2:V1的普通变量(无装饰器)在V2中只能用`@Param`接收;V1的状态变量(有装饰器)在V2中只能用`@Param`接收,且只支持简单类型(boolean, number, enum, string, undefined, null)。 - V2递给V1:V2的普通变量在V1中只能用`@State`、`@Prop`、`@Provide`接收;V2的状态变量在V1中接收时,不支持内置复杂类型(Array, Set, Map, Date)。 2. **V2自定义组件使用V1组件的规则**: - V2自定义组件中不能使用V1装饰器,否则编译报错。 - 当组件间没有变量递时,V2组件可以使用V1组件(包括第三方V1组件)。 - 当组件间有变量递时,规则如上所述。 3. **迁移**:提供了从V1迁移到V2的指南。 现在,我们需要讲解组件通信中V1和V2版本的差异及实现方式。我们将从以下几个方面展开: - 装饰器差异 - 组件通信方式(父子组件、兄弟组件等)在V1和V2中的实现 - 状态管理能力(如嵌套对象观测、计算属性等) - 性能优化 由于引用[1]主要涉及混用规则,我们还需要结合之前回答中关于状态管理V1和V2的区别(如深度观测、计算属性等)来补充。 **结构安排**: 1. **组件通信基础**:简要说明组件通信的常见场景(父子、兄弟、跨级等)。 2. **V1状态管理(装饰器)**:介绍V1中用于组件通信的装饰器(如`@State`、`@Prop`、`@Link`、`@Provide`、`@Consume`等)及其使用方式。 3. **V2状态管理(装饰器)**:介绍V2中的新装饰器(`@Local`、`@Param`、`@Computed`、`@ObservedV2`、`@Trace`等)及其优势。 4. **通信方式对比**: - 父子组件通信 - 兄弟组件通信 - 跨级组件通信 - 全局通信 5. **混用规则**:根据引用[1]详细说明V1和V2组件混用时的限制。 6. **迁移建议**:如何从V1迁移到V2。 7. **示例对比**:通过具体示例展示V1和V2在组件通信中的实现差异。 **注意**:在回答中,我们将使用引用[1]的内容,并在适当位置标注引用。 下面开始组织回答:</think>### 鸿蒙系统组件通信 V1 与 V2 的区别及实现方式 在鸿蒙系统中,组件通信的 V1(API 9)和 V2(API 10+)版本在**装饰器机制**、**状态管理能力**和**数据类型支持**上有显著差异。以下是核心区别及实现方式: --- #### 一、装饰器机制对比 | **特性** | **V1 状态管理** | **V2 状态管理** | |-------------------|--------------------------------|--------------------------------| | **核心装饰器** | `@State`/`@Prop`/`@Link` | `@Local`/`@Param`/`@Trace` | | **状态共享** | `@Provide`/`@Consume` | `@ObservedV2`+`@Trace` | | **计算属性** | 不支持 | `@Computed` 自动缓存计算 [^1] | | **深度观测** | 需手动触发更新 | 嵌套对象自动观测更新 [^1] | --- #### 二、组件通信实现方式 ##### 1. **父子组件通信** - **V1 实现** 父组件通过 `@State` 递简单类型数据,子组件用 `@Prop` 接收: ```typescript // 父组件 @State message: string = "Hello V1" build() { ChildComponent({ message: this.message }) } // 子组件 @Prop message: string ``` 复杂类型(如对象)需手动序列化/反序列化。 - **V2 实现** 直接递对象,子组件用 `@Param` 接收并自动观测嵌套属性: ```typescript // 父组件 @Local product: Product = { id: "P001", price: 99.9 } build() { ChildComponent({ product: this.product }) } // 子组件 @Param product: Product // 自动观测 product.price 变化 ``` ##### 2. **跨级组件通信** - **V1 实现** 使用 `@Provide`/`@Consume` 跨层级递,**仅支持简单类型**: ```typescript // 祖先组件 @Provide('theme') themeColor: string = "blue" // 后代组件 @Consume('theme') themeColor: string ``` - **V2 实现** 通过 `@ObservedV2` 实现深度观测,支持复杂对象: ```typescript // 共享状态类 @ObservedV2 class ThemeStore { @Trace color: string = "blue" @Trace fontSize: number = 16 } // 任意层级组件 @Local theme: ThemeStore = new ThemeStore() ``` ##### 3. **兄弟组件通信** - **通用方案** 两者均需通过父组件中转或使用全局状态管理(如 AppStorage): ```typescript // V1/V2 通用(AppStorage) AppStorage.SetOrCreate('count', 0) // 组件A AppStorage.Set('count', 10) // 组件B @StorageLink('count') count: number // 自动更新 ``` --- #### 三、数据类型支持差异 | **数据类型** | **V1 支持情况** | **V2 支持情况** | |--------------------|-------------------------------|-------------------------------| | 基本类型 | ✅ (string/number/boolean) | ✅ | | 简单对象 | ⚠️ 需手动序列化 | ✅ 自动观测 | | 嵌套对象 | ❌ 无法深度观测 | ✅ `@Trace` 实现深度观测 [^1] | | 数组(Array) | ❌ 元素变更需整体替换 | ✅ 元素级自动观测 | | 集合(Set/Map) | ❌ 不支持 | ✅ 支持 | | 日期(Date) | ❌ 不支持 | ✅ 支持 | --- #### 四、混用规则(V1 与 V2 组件交互) 根据引用[1],混用时需遵守: 1. **V1 → V2 递数据** - V1 普通变量 → V2 只能用 `@Param` 接收 - V1 状态变量 → V2 仅支持简单类型(boolean/number/string/enum) ```typescript // V1 父组件 @State count: number = 0 build() { V2Child({ count: this.count }) // ✅ 允许 } // V2 子组件 @Param count: number // ✅ 正确 ``` 2. **V2 → V1 递数据** - V2 状态变量 → V1 不支持复杂类型(Array/Set/Map/Date) - V2 普通变量 → V1 只能用 `@State`/`@Prop`/`@Provide` 接收 ```typescript // V2 父组件 @Local user: User = { name: "Alice" } build() { V1Child({ user: this.user }) // ❌ 禁止!V1 不支持对象 } ``` > ⚠️ **关键限制**: > - V1 组件中**不能使用 V2 装饰器**(如 `@Local`) > - V2 组件中**不能使用 V1 装饰器**(如 `@Provide`) > - 违反将导致编译错误 [^1] --- #### 五、迁移建议 1. **新项目** 直接采用 V2 状态管理,使用 `@ObservedV2`+`@Trace` 实现深度观测,`@Computed` 优化计算逻辑。 2. **旧项目升级** 通过 `@EnableV2Compatibility` 逐步迁移: ```typescript // 在 V2 组件中兼容 V1 状态 @Param legacyData: LegacyData = UIUtils.enableV2Compatibility(new LegacyData()) ``` 3. **混合开发** - 优先在边界组件(如页面入口)处理数据类型转换 - 复杂场景使用 AppStorage 作为中间层 - 避免跨版本直接递嵌套对象 > **总结**:V2 通过深度观测和类型扩展,显著提升了组件通信的效率和可维护性。对于复杂应用,建议全面迁移至 V2 状态管理 [^1]。 --- ### 相关问题 1. 如何在 V2 状态管理中实现跨设备组件通信? 2. `@Trace` 装饰器对嵌套对象观测的具体实现原理是什么? [^1] 3. 混用 V1/V2 组件时,如何优化数据输性能? 4. V2 的 `@Computed` 装饰器在组件通信中有哪些典型应用场景? [^1] 5. 如何通过状态管理 V2 实现组件间的双向数据绑定? [^1]: 引用自华为开发者文档:[鸿蒙状态管理 V1 到 V2 迁移指南](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-v1-v2-migration-V14)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodingFire

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值