在Vue3中,子组件向父组件传递数据主要通过自定义事件的方式实现,核心原理是子组件通过emit触发事件并携带数据,父组件监听该事件并接收数据。以下是具体实现方法和示例:
方法说明
- 子组件:通过
emit方法触发一个自定义事件,并将需要传递的数据作为参数传入。- 在
<script setup>中,需先从vue导入defineEmits定义事件。
- 在
- 父组件:在使用子组件时,通过
@自定义事件名监听事件,并在事件处理函数中接收子组件传递的数据。
示例1:基础用法(点击按钮传递数据)
子组件(Child.vue)
<template>
<!-- 点击按钮时触发事件,传递数据 -->
<button @click="sendData">向父组件传递数据</button>
</template>
<script setup>
// 定义子组件可触发的事件("send-message" 为自定义事件名)
const emit = defineEmits(['send-message'])
// 子组件的方法:触发事件并携带数据
const sendData = () => {
const message = "我是子组件传递的数据"
// 触发事件,第一个参数是事件名,第二个参数是要传递的数据
emit('send-message', message)
}
</script>
父组件(Parent.vue)
<template>
<div>
<!-- 监听子组件的 "send-message" 事件,并用 handleMessage 处理 -->
<Child @send-message="handleMessage" />
<!-- 显示子组件传递的数据 -->
<p>父组件接收的数据:{{ receivedData }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
// 父组件存储接收的数据
const receivedData = ref('')
// 处理子组件传递的数据
const handleMessage = (data) => {
receivedData.value = data // 将子组件数据赋值给父组件变量
}
</script>
示例2:实时传递输入框数据
更常见的场景是子组件实时传递用户输入(如表单),父组件实时响应。
子组件(InputChild.vue)
<template>
<!-- 输入框变化时触发事件 -->
<input
type="text"
v-model="inputValue"
@input="handleInput"
placeholder="输入内容传递给父组件"
>
</template>
<script setup>
import { ref } from 'vue'
// 定义可触发的事件
const emit = defineEmits(['input-change'])
// 子组件的输入值
const inputValue = ref('')
// 输入变化时触发事件,传递最新值
const handleInput = () => {
emit('input-change', inputValue.value)
}
</script>
父组件(InputParent.vue)
<template>
<div>
<InputChild @input-change="handleInputChange" />
<p>父组件实时显示:{{ inputData }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
import InputChild from './InputChild.vue'
const inputData = ref('')
// 实时接收子组件的输入值
const handleInputChange = (value) => {
inputData.value = value
}
</script>
示例3:使用v-model简化(双向绑定)
如果需要实现“子组件修改数据,父组件同步更新”的双向绑定效果,可以利用 v-model 语法糖(本质仍是自定义事件)。
子组件(VModelChild.vue)
<template>
<input
type="text"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
</template>
<script setup>
// 接收父组件通过v-model传递的默认值
defineProps(['modelValue'])
// 声明更新事件(固定格式:update:modelValue)
defineEmits(['update:modelValue'])
</script>
父组件(VModelParent.vue)
<template>
<div>
<!-- 用v-model绑定,等价于 @update:modelValue="value = $event" -->
<VModelChild v-model="parentValue" />
<p>v-model绑定的值:{{ parentValue }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
import VModelChild from './VModelChild.vue'
const parentValue = ref('初始值')
</script>
核心总结
- 子传父的核心是 “子组件emit事件,父组件监听事件”。
<script setup>中需通过defineEmits声明事件,确保类型约束和代码可读性。- 复杂场景(如多层级组件)可考虑Vuex/Pinia或
provide/inject,但父子直接通信优先使用自定义事件。
1万+

被折叠的 条评论
为什么被折叠?



