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 触发事件

  • 优点
    • 降低组件间耦合
    • 符合单向数据流原则
    • 子组件不需要知道父组件如何处理事件
  • 缺点
    • 无法直接获取返回值
    • 事件名称需要维护

最佳实践

  1. 使用 Props 传递函数:当子组件需要直接调用父组件方法并获取返回值时

  2. 使用 Emit 触发事件:当子组件只需通知父组件状态变化,不关心父组件如何处理时

  3. 混合使用:复杂场景下可以结合两种方式使用,保持组件间的清晰通信

在 Vue 3 的组合式 API 中,这两种通信方式都得到了很好的类型支持,使用 definePropsdefineEmits 可以获得完整的类型提示。


更新时间:2025-03-13 21:38