使用回调函数的方法实现子组件向父组件传值
- 1 主要内容说明
- 2 实现步骤
- 2.1 父组件中定义回调函数
- 2.2 子组件声明并调用回调函数
- 2.3 注意事项
- 3 源码
- 3.1 父组件
- 3.2 子组件
- 3.3 源码效果显示截图
- 4 结语
- 5 定位日期
1 主要内容说明
本文源码是一套 父组件与子组件之间双向数据传递的示例代码。
-
父组件 Index
用户在输入框中输入内容,点击按钮后将数据传递给子组件。
同时也可以接收子组件传回的数据并展示。
-
子组件 childPage
接收父组件传过来的内容并显示。
允许用户在子组件中输入数据,点击按钮后通过回调函数传回给父组件。
在 ArkTS 中,若不使用@Link 或 @Provide+@Consume 进行组件间的数据双向同步,则可以通过回调函数(函数作为参数) 的方式,实现在子组件中触发父组件的逻辑,从而实现“子传父”的功能,再结合@Prop父传子的单向传递,则可实现两组件的数据双向传递。
2 实现步骤
2.1 父组件中定义回调函数
- 这个函数接收子组件传来的数据,然后用于更新父组件自己的状态。
@State showTextChild: string = ""
childPage({
onClickText: (val) => {
this.showTextChild = val // 子组件传来的内容
}
})
2.2 子组件声明并调用回调函数
- 使用一个函数属性接收父组件传进来的方法
- 在需要的时候调用这个函数(如点击按钮时)
// 子组件属性定义
onClickText: (val: string) => void = () => {}
// 点击时触发回调
Button("将信息传给父组件")
.onClick(() => {
this.onClickText(this.textChild)
})
2.3 注意事项
- 子组件中不能直接使用 @Prop 修改数据,只能“读取”。
- 通过函数传递,数据流仍然是“单向”的,但逻辑上实现了“子组件触发父组件的状态更新”。
- 默认值 ()=>{} 是为了防止父组件没有传入函数时报错。
3 源码
3.1 父组件
这一段是父组件逻辑。它的核心点:
- 输入 → textContent
- 点击按钮 → textData(传给子组件)
- 子组件通过 onClickText 回调把数据传回父组件 → showTextChild
/**
* 通过对象的方式父组件和子组件间进行数据传输
*/
import { childPage } from './childPage' // 引入子组件
@Entry
@Component
struct Index {
// 父组件内部用来接收输入框实时输入的内容
@State textContent: string = "接收输入框的内容"
// 实际传递给子组件显示的内容,只有点击按钮才会更新
@State textData: string = "传递给子组件的内容"
// 用来接收子组件传回来的内容
@State showTextChild: string = ""
build() {
Column() {
// 父组件标题
Text("父组件")
.fontSize(20)
.fontWeight(FontWeight.Bold)
// 输入框,输入内容会实时保存在 textContent 中
TextInput({ placeholder: "父组件输入的内容" })
.width("90%")
.margin({ top: 20 })
.onChange((val) => {
this.textContent = val // 实时更新输入内容
})
// 显示当前将要传给子组件的内容
Text(this.textData)
.margin({ top: 20 })
// 按钮点击后才把输入框内容赋值到 textData,从而传给子组件
Button("点击父组件数据传到子组件")
.margin({ top: 20, bottom: 50 })
.onClick(() => {
this.textData = this.textContent
})
// 显示从子组件传回来的内容
Text("子组件传来的信息:" + this.showTextChild)
.margin({ bottom: 30 })
// 使用子组件 childPage,并通过对象方式传值
childPage({
ShowText: this.textData, // 父传子:通过 Props 将 textData 传给子组件
onClickText: (val) => { // 子传父:当子组件触发回调时,把数据赋值到 showTextChild
this.showTextChild = val
}
})
}
.width("100%") // 设置整个页面宽度为 100%
}
}
3.2 子组件
功能 | 实现方式 |
---|---|
接收父组件传值 | @Prop ShowText: string |
显示传入内容 | Text(“显示父组件传过来的内容:” + this.ShowText) |
接收用户输入 | TextInput 的 onChange 设置 textChild |
子传父数据 | 通过调用 onClickText(this.textChild) |
/**
* 子组件
*/
@Component
export struct childPage {
// 使用 @Prop 装饰器接收父组件传递的数据,支持响应式更新
@Prop ShowText: string = "子组件默认初始内容"
// 声明一个函数类型的属性,用于回调传值给父组件,初始为一个空函数避免报错
onClickText: (val: string) => void = () => {}
// 子组件内部保存要传回父组件的文本内容
textChild: string = ""
build() {
Column({ space: 20 }) {
// 显示标题
Text("调用的子组件")
.fontSize(18)
.fontWeight(FontWeight.Bold)
// 显示父组件传过来的内容
Text("显示父组件传过来的内容:" + this.ShowText)
.fontSize(15)
.fontWeight(FontWeight.Bold)
.margin({ top: 50 })
// 子组件的输入框,用于输入要传给父组件的内容
TextInput({ placeholder: "输入子组件的内容,传递给父组件" })
.width("90%")
.onChange((val) => {
this.textChild = val // 将输入内容保存到 textChild
})
// 点击按钮后触发回调,把输入的内容传递给父组件
Button("将信息传给父组件")
.onClick(() => {
this.onClickText(this.textChild) // 调用父组件传来的回调函数
})
}
.width("90%") // 设置子组件宽度
.height("50%") // 设置子组件高度
.padding(10) // 添加内边距
.border({ width: 2, color: "#fcc", radius: 8 }) // 边框样式
.shadow({ radius: 18, color: "#ff589f3c", offsetX: 9, offsetY: 9 }) // 阴影效果
}
}
3.3 源码效果显示截图
4 结语
在某种情况下,父组件需要对各个子组件分别控制,设置不同的内容属性,而子组件返回的参数内容,可以是数据和对象,需要分别进行处理。此时可以尝试使用回调函数的方法实现两组件间的数据传递,便于控制。
两组间间的传值也可以使用@Link 或 @Provide+@Consume,根据实际情况选择合适的传值方式便可。
华为官方@Prop装饰器的参考指南@Prop装饰器:父子单向同步
由于笔者的能力有限,创作的内容有所不足在所难免,也敬请读者包涵和指出,万分感谢!
5 定位日期
2025-04-19;
12:51;