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

本文介绍了在前端开发中,父子组件间两种常见的通信方式:属性传值和广播传值。属性传值通过子组件声明props接收父组件传递的数据,而广播传值则利用事件机制实现从父到子的数据推送。

父子组件传递信息有两种方法:
1.属性传值;
2.广播传值;

1)属性传值相对简单,即在子组件中用props声明属性,然后在父组件中使用时进行赋值,说起来简单,下面来说说具体怎么用:

//子组件 child.ux
props: [
      'name',
      'age'
       ]

//父组件内使用子组件
<child name="{{user_name}}" age="{{user_age}}"> </child>
然后可以对括号中的变量进行操作赋值,这样就完成了对子组件的传值操作。

2)广播传值
在父组件中:

//在你需要触发的地方写
 this.$broadcast("evtType1",{'infro': "华为快应用"});

在子组件中:

        onInit:function() {
            //注册通知
            this.$on('evtType1', this.evtTypeHandler)
        },
        data () {
            return {
                //这是变量名
                changeStr: '默认'
            }
        },
        evtTypeHandler(evt) {
            console.info('子组件:事件响应: ', evt.type, evt.detail)
            // 结束事件传递
            // evt.stop() 如果你希望只传递一次,就写上这句话,如果需要多次传递就千万不能写
            //给变量赋传递过来的值
            this.changeStr = evt.detail.changeStr;
        },
<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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CodingFire

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

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

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

打赏作者

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

抵扣说明:

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

余额充值