Vue 3 父子组件通信详解:子组件调用父组件方法

发表于 2025-09-19 00:12:18 分类于 默认分类 阅读量 64

Vue 3 父子组件通信详解:子组件调用父组件方法

在 Vue 3 开发中,父子组件之间的通信是非常常见的需求。特别是当子组件(例如一个 Header)需要调用父组件的方法时,有几种标准的实现方式。本篇文章将详细讲解 Vue 3 中父子组件通信的几种方案,并给出完整示例。


一、通过 props 传递父组件方法

这是最直接的一种方式,父组件将方法以 props 的形式传递给子组件,子组件直接调用即可。

父组件示例

<template>
  <div>
    <Header :onAction="handleHeaderAction" />
    <p>父组件内容显示:{{ message }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import Header from './Header.vue'

const message = ref('')

function handleHeaderAction(payload) {
  message.value = `父组件方法被调用,参数:${payload}`
  console.log('父组件方法被调用', payload)
}
</script>

子组件示例 (Header.vue)

<template>
  <button @click="callParent">点击调用父组件方法</button>
</template>

<script setup>
import { defineProps } from 'vue'

const props = defineProps({
  onAction: Function
})

function callParent() {
  if (props.onAction) {
    props.onAction('子组件传的参数')
  }
}
</script>

✅ 优点:简单直观,直接传函数调用。


二、通过自定义事件 (emit) 调用父组件方法(推荐)

这种方式符合 Vue 的单向数据流设计,更加解耦,推荐在组件库或复杂项目中使用。

父组件示例

<template>
  <div>
    <Header @action="handleHeaderAction" />
    <p>父组件内容显示:{{ message }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import Header from './Header.vue'

const message = ref('')

function handleHeaderAction(payload) {
  message.value = `父组件方法被调用,参数:${payload}`
  console.log('父组件方法被调用', payload)
}
</script>

子组件示例 (Header.vue)

<template>
  <button @click="callParent">点击调用父组件方法</button>
</template>

<script setup>
import { defineEmits } from 'vue'

const emit = defineEmits(['action'])

function callParent() {
  emit('action', '子组件传的参数')
}
</script>

✅ 优点:解耦性好,符合 Vue 设计思想,事件机制清晰。


三、通过 ref 获取子组件实例(父组件调用子组件方法)

虽然这种方式通常是父组件调用子组件方法,但也可以作为特殊场景的解决方案:

父组件示例

<template>
  <Header ref="headerRef" />
  <button @click="callChildMethod">调用子组件方法</button>
</template>

<script setup>
import { ref } from 'vue'
import Header from './Header.vue'

const headerRef = ref(null)

function callChildMethod() {
  headerRef.value.someChildMethod()
}
</script>

子组件示例 (Header.vue)

<script setup>
function someChildMethod() {
  console.log('子组件方法被调用')
}
</script>

⚠️ 注意:这种方式适用于父组件主动调用子组件方法,不推荐用来让子组件直接调用父组件方法。


四、总结

  • 推荐方式:通过自定义事件 emit 调用父组件方法,解耦性强、可维护性好。
  • 简单方式:通过 props 直接传递父组件方法,快速实现。
  • 不推荐方式:通过 ref 获取父组件实例或子组件实例来调用方法,维护成本高。

在实际开发中,如果你的子组件需要多次与父组件交互,强烈建议使用事件 emit,保证组件的独立性和可复用性。


示例效果

子组件点击按钮后,父组件会接收到事件并更新页面显示:

子组件传的参数 -> 父组件内容显示:父组件方法被调用,参数:子组件传的参数

这样就实现了完整的父子组件通信。