鸿蒙开发中父子组件如何进行数据通信(状态管理v1版)?
2025-01-03 10:57:44
39次阅读
0个评论
【问题描述】:我们经常在开发的时候,需要在父子组件进行数据的传递,有哪几种常见的用法?
【解决方案】:以下几种解决方案可以满足70%的应用场景。
一、@state 和 @prop
1.@State:装饰的变量值修改时,页面也会随之更新
2.@Prop: 配合@State使用,实现页面单向传递 数据从父组件传入子组件,父组件数据修改,子组件UI更新;在子组件中修改,父组件ui不更新 (传递值时使用this.)
代码示例
父组件
import Child from '../view/Child'//引入子组件
@Entry
@Component
struct Index {
@State showNumber2:number=0
build() {
Column() {
Row() {
Text('showNumber2:'+this.showNumber2)
.fontSize(40)
}
.width('100%')
Row() {
Button('加1').width('100%').height(50).onClick(()=>{
this.showNumber2++
})
}
.width('100%')
//子组件
Row(){
Child({
showNumber2:this.showNumber2,
//由于@Prop装饰器是单向传递 所以可以使用回调函数的方式来修改父组件的值
giveIndex:(data)=>{
if(data){
this.showNumber2=parseInt(data)
}else {
this.showNumber2=0
}
}})
}.width('100%')
}
.height('100%')
.width('100%')
}
}
子组件
@Component
export default struct Child {
@Prop showNumber2:number
// 回调函数
giveIndex=(data)=>{
}
build() {
Column() {
Row() {
Text('@Prop装饰器:')
TextInput({text:JSON.stringify(this.showNumber2)})
.width('100%')
.type(InputType.Number)
.height(50)
.onChange((value)=>{
//使用回调可以修改父组件的值
//this.giveIndex(value)
//传入修改无效
if(value){
this.showNumber2=parseInt(value)
}else {
this.showNumber2=0
}
})
}
.width('50%')
}
}
}
二、@state 和 @Link:
配合@State使用,子组件用@Link接收, 可以实现页面双向传递 数据从父组件传入子组件,在子组件中修改则父组件ui更新 (传递值时使用$)
父组件
import Child from '../view/Child'//引入子组件
@Entry
@Component
struct Index {
@State showNumber1:number=0
build() {
Column() {
Row() {
Text('showNumber1:'+this.showNumber1)
.fontSize(40)
}
.width('100%')
Row() {
Button('加1').width('100%').height(50).onClick(()=>{
this.showNumber1= this.showNumber1+1
})
}
.width('100%')
Row(){
Child({showNumber1:$showNumber1}) //注意这里传参是用的$
}.width('100%')
}
.height('100%')
.width('100%')
}
}
子组件
@Component
export default struct Child {
@Link showNumber1:number
build() {
Column() {
Row() {
Text('@Link装饰器:')
TextInput({text:JSON.stringify(this.showNumber1)})
.width('100%')
.type(InputType.Number)
.height(50)
.onChange((value)=>{
if(value){
this.showNumber1=parseInt(value)
}else {
this.showNumber1=0
}
})
}
.width('50%')
}
}
}
三 、@Provide 和 @Consume
1、@Provide/@Consume 配套使用,可以跨组件传值并且双向同步,在调用组件时不需要传递参数,能直接获取,ui更新 (不需要再组件调用中传值)
2、不同于上文提到的父子组件之间通过命名参数机制传递,@Provide和@Consume摆脱参数传递机制的束缚,实现跨层级传递 父组件:
import Child from '../view/Child'//引入子组件
@Entry
@Component
struct Index {
@Provide showNumber: number = 0
build() {
Column() {
Row() {
Text('showNumber:'+this.showNumber)
.fontSize(40)
}
.width('100%')
Row() {
Button('加1').width('100%').height(50).onClick(()=>{
this.showNumber= this.showNumber+1
})
}
.width('100%')
Row(){
Child() // 子组件
}.width('100%')
}
.height('100%')
.width('100%')
}
}
子组件:
@Component
export default struct Child {
@Consume showNumber:number
build() {
Column() {
Row() {
Text('@Provide装饰器:')
TextInput({text:JSON.stringify(this.showNumber)})
.width('100%')
.type(InputType.Number)
.height(50)
.onChange((value)=>{
if(value){
this.showNumber=parseInt(value)
}else {
this.showNumber=0
}
})
}
.width('50%')
}
}
}
四 、@Watch装饰器:状态变量更改通知
@Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数
@Component
struct Child {
@Prop @Watch('onCountUpdated') count: number = 0;
@State total: number = 0;
// @Watch 回调
onCountUpdated(propName: string): void {
this.total += this.count;
}
build() {
Text(`Total: ${this.total}`)
}
}
@Entry
@Component
struct Index {
@State count: number = 0;
build() {
Column() {
Button('add to basket')
.onClick(() => {
this.count++
})
Child({ count: this.count })
}
}
}
五、@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化
对象嵌套两层之后,状态更新失去了响应性,这时候需要用到@Observed装饰器和@ObjectLink装饰器
// Index.ets
// Child
@Observed
class objA {
public c: string;
constructor(c: string) {
this.c = c;
}
}
@Observed
class objB {
public a: objA;
public b: string;
constructor(a: objA, b: string) {
this.a = a;
this.b = b;
}
}
@Component
struct Child {
@ObjectLink a:objA
build() {
Text(this.a.c).fontSize(50)
.onClick(()=>{
this.a.c = 'ca';
})
}
}
@Entry
@Component
struct Index {
@State b: objB = new objB(new objA('a'),'b');
build() {
Column(){
Child({a:this.b.a})
}
.width('100%')
.onClick(()=>{
this.b.a.c='pa'
})
}
}
点击父元素,可以实现给b.a.c赋值’pa’;
点击子组件,可以实现给a.c 赋值 ‘ca’
00
- 0回答
- 0粉丝
- 0关注
相关话题
- HarmonyOS NEXT跨多个组件之间如何进行数据通信?
- 【HarmonyOS Next】状态管理V2版本使用详解
- 状态管理概述
- HarmonyOS Next V2 状态管理AppStorageV2和PersistenceV2
- 如何获取状态管理框架代理前的原始对象
- 【HarmonyOS NEXT】鸿蒙 ArkTS 进行RSA数据加密
- 如何获取设备屏幕横竖屏状态
- 【HarmonyOS NEXT】Web 组件的基础用法以及 H5 侧与原生侧的双向数据通讯
- 「Mac玩转仓颉内测版32」基础篇12 - Cangjie中的变量操作与类型管理
- OpenHarmony: 如何删除Record中的元素
- 如何在Page中获取WindowStage实例
- 「Mac畅玩鸿蒙与硬件16」鸿蒙UI组件篇6 - List和Grid组件展示数据列表
- 「Mac畅玩鸿蒙与硬件 11」鸿蒙UI组件篇1 - Text和Button组件详解
- ArkData 存-管-同-享的数据管理理念
- 「Mac畅玩鸿蒙与硬件1」鸿蒙开发环境配置篇1 - 认识鸿蒙系统与开发工具