Vue3后代传祖先组件通讯方法
在 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>
最佳实践选择:
-
简单通信:优先使用
provide/inject
-
跨组件通信:推荐使用事件总线
-
复杂状态管理:使用 Pinia/Vuex
-
直接组件引用:模板引用 + expose
注意:provide/inject 需要确保在组件树中存在提供者,事件总线要注意及时移除监听避免内存泄漏,状态管理适用于需要持久化或共享的数据。