在 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 需要确保在组件树中存在提供者,事件总线要注意及时移除监听避免内存泄漏,状态管理适用于需要持久化或共享的数据。