Vue3后代传祖先组件通讯方法

发布于:2025-04-21 ⋅ 阅读:(52) ⋅ 点赞:(0)

在 Vue3 中,后代组件向祖先组件通信可以通过以下几种方式实现:

方式一:Provide/Inject + 函数传递(推荐)

vue

<!-- 祖先组件 -->
<script setup>
import { provide } from 'vue'

const handleChildMsg = (msg) => {
  console.log('收到后代消息:', msg)
}

// 提供函数给后代
provide('sendToAncestor', handleChildMsg)
</script>

<!-- 后代组件 -->
<script setup>
import { inject } from 'vue'

// 注入祖先提供的函数
const send = inject('sendToAncestor')

const sendMessage = () => {
  send('来自后代的消息')
}
</script>

方式二:自定义事件总线

javascript

// eventBus.js
import mitt from 'mitt'
export const emitter = mitt()

vue

复制

<!-- 祖先组件 -->
<script setup>
import { onMounted, onUnmounted } from 'vue'
import { emitter } from './eventBus'

const handleEvent = (msg) => {
  console.log('收到消息:', msg)
}

onMounted(() => {
  emitter.on('child-message', handleEvent)
})

onUnmounted(() => {
  emitter.off('child-message', handleEvent)
})
</script>

<!-- 后代组件 -->
<script setup>
import { emitter } from './eventBus'

const emitToAncestor = () => {
  emitter.emit('child-message', '后代发送的消息')
}
</script>

方式三:Vuex/Pinia 状态管理

javascript

// store.js
import { defineStore } from 'pinia'

export const useMainStore = defineStore('main', {
  state: () => ({
    messageFromDescendant: null
  }),
  actions: {
    setMessage(msg) {
      this.messageFromDescendant = msg
    }
  }
})

vue

<!-- 祖先组件 -->
<script setup>
import { useMainStore } from './store'
import { watch } from 'vue'

const store = useMainStore()

watch(
  () => store.messageFromDescendant,
  (newVal) => {
    console.log('收到消息:', newVal)
  }
)
</script>

<!-- 后代组件 -->
<script setup>
import { useMainStore } from './store'

const store = useMainStore()

const sendMessage = () => {
  store.setMessage('后代发送的消息')
}
</script>

方式四:模板引用(多层组件时)

vue

<!-- 祖先组件 -->
<script setup>
import { ref } from 'vue'

const lastChildRef = ref(null)

const handleChildMsg = (msg) => {
  console.log('收到消息:', msg)
}

// 通过 expose 暴露方法
defineExpose({ handleChildMsg })
</script>

<template>
  <ParentComponent>
    <ChildComponent ref="lastChildRef" />
  </ParentComponent>
</template>

最佳实践选择:

  1. 简单通信:优先使用 provide/inject

  2. 跨组件通信:推荐使用事件总线

  3. 复杂状态管理:使用 Pinia/Vuex

  4. 直接组件引用:模板引用 + expose

注意:provide/inject 需要确保在组件树中存在提供者,事件总线要注意及时移除监听避免内存泄漏,状态管理适用于需要持久化或共享的数据。