Vue 组件通信:Props 传递函数 vs. Emit 触发事件
发布时间:2025-02-28 01:27
在 Vue 3 中,组件间通信主要有两种方式:通过 props 传递函数和通过 emit 触发事件。这两种方式各有特点和适用场景。
基本区别
Props 传递函数
- 方向:父组件 → 子组件
- 本质:将父组件的方法作为属性传递给子组件
- 适用场景:当父组件需要提供功能给子组件调用时
Emit 触发事件
- 方向:子组件 → 父组件
- 本质:子组件触发一个自定义事件,父组件监听并响应
- 适用场景:当子组件需要通知父组件某些状态变化时
代码示例
使用 Props 传递函数
父组件:
<script setup lang="ts">
import ChildComponent from './ChildComponent.vue';
const handleAction = (value: string) => {
console.log('父组件方法被调用:', value);
};
</script>
<template>
<div class="p-4">
<h2 class="text-xl font-bold mb-4">父组件</h2>
<ChildComponent :onAction="handleAction" />
</div>
</template>
子组件:
<script setup lang="ts">
defineProps<{
onAction: (value: string) => void
}>();
</script>
<template>
<div class="border p-3 rounded">
<h3 class="text-lg mb-2">子组件</h3>
<button
class="bg-blue-500 text-white px-4 py-2 rounded"
@click="onAction('来自子组件的数据')">
调用父组件方法
</button>
</div>
</template>
使用 Emit 触发事件
父组件:
<script setup lang="ts">
import ChildComponent from './ChildComponent.vue';
const handleCustomEvent = (value: string) => {
console.log('接收到子组件事件:', value);
};
</script>
<template>
<div class="p-4">
<h2 class="text-xl font-bold mb-4">父组件</h2>
<ChildComponent @custom-event="handleCustomEvent" />
</div>
</template>
子组件:
<script setup lang="ts">
const emit = defineEmits<{
(e: 'custom-event', value: string): void
}>();
const triggerEvent = () => {
emit('custom-event', '来自子组件的数据');
};
</script>
<template>
<div class="border p-3 rounded">
<h3 class="text-lg mb-2">子组件</h3>
<button
class="bg-green-500 text-white px-4 py-2 rounded"
@click="triggerEvent">
触发事件通知父组件
</button>
</div>
</template>
两种方式的优缺点
Props 传递函数
- 优点:
- 直接调用父组件方法,代码更直观
- 可以立即获得返回值
- 缺点:
- 增加了组件间的耦合度
- 子组件依赖父组件提供的方法
Emit 触发事件
- 优点:
- 降低组件间耦合
- 符合单向数据流原则
- 子组件不需要知道父组件如何处理事件
- 缺点:
- 无法直接获取返回值
- 事件名称需要维护
最佳实践
-
使用 Props 传递函数:当子组件需要直接调用父组件方法并获取返回值时
-
使用 Emit 触发事件:当子组件只需通知父组件状态变化,不关心父组件如何处理时
-
混合使用:复杂场景下可以结合两种方式使用,保持组件间的清晰通信
在 Vue 3 的组合式 API 中,这两种通信方式都得到了很好的类型支持,使用 defineProps
和 defineEmits
可以获得完整的类型提示。
更新时间:2025-03-13 21:38