Vue.js中不使用Event Bus或父组件,兄弟组件间还有其他传值方式吗?
Great question! I’ve run into this exact scenario plenty of times—luckily, Vue.js gives us several solid alternatives to Event Bus or relying on parent component mediation for sibling-to-sibling data transfer. Let’s break them down based on your project size and needs:
State Management Libraries (Vuex for Vue 2, Pinia for Vue 3)
This is the go-to solution for medium to large apps where you need tracked, predictable state flow. Instead of passing data through components, you store shared state in a global store that both siblings can access directly.Example with Pinia (Vue 3):
// stores/sharedStore.js import { defineStore } from 'pinia' export const useSharedStore = defineStore('shared', { state: () => ({ siblingData: null }), actions: { updateSiblingData(newData) { this.siblingData = newData } } })In Component A (sender):
<script setup> import { useSharedStore } from '@/stores/sharedStore' const store = useSharedStore() const sendToSibling = () => { store.updateSiblingData('Hey from Component A!') } </script>In Component B (receiver):
<script setup> import { useSharedStore } from '@/stores/sharedStore' const store = useSharedStore() </script> <template> <p>{{ store.siblingData }}</p> </template>This keeps state changes traceable and avoids "prop drilling" or messy event chains.
Provide/Inject (Vue 2.2+ & Vue 3)
While often used for grandparent-grandchild communication, you can leverage this pattern for siblings too—without making the parent handle any data logic. Just have their common parent (or even the root app) "provide" a reactive value, and both siblings "inject" it.Example in Vue 3:
Parent component (only acts as a provider, no data handling):<script setup> import { ref, provide } from 'vue' const sharedData = ref(null) provide('sharedData', sharedData) </script> <template> <ComponentA /> <ComponentB /> </template>Component A:
<script setup> import { inject } from 'vue' const sharedData = inject('sharedData') const updateData = () => { sharedData.value = 'Updated from Component A' } </script>Component B:
<script setup> import { inject } from 'vue' const sharedData = inject('sharedData') </script> <template> <p>{{ sharedData }}</p> </template>
Shared Composition API Module (Vue 3)
For small apps or simple shared state, you can create a standalone reactive state module that both siblings import directly. No need for heavy state management libraries.Example:
// src/composables/sharedState.js import { ref } from 'vue' // Reactive value shared across components export const sharedValue = ref(null) // Helper function to update the value export const updateSharedValue = (newVal) => { sharedValue.value = newVal }Component A:
<script setup> import { updateSharedValue } from '@/composables/sharedState' </script> <template> <button @click="updateSharedValue('Hi from A!')">Send to B</button> </template>Component B:
<script setup> import { sharedValue } from '@/composables/sharedState' </script> <template> <p>{{ sharedValue }}</p> </template>This is super lightweight and perfect for quick, low-complexity use cases.
Browser Storage (LocalStorage/SessionStorage)
If your data doesn’t need real-time reactivity (or you’re willing to listen for storage events), browser storage works as a quick cross-component data bridge. Just note that data is stored as strings, so you’ll need to serialize objects withJSON.stringify()/JSON.parse().Example:
Component A:<script setup> const sendData = () => { localStorage.setItem('siblingData', 'Hello from Component A') } </script>Component B:
<script setup> import { ref, onMounted } from 'vue' const data = ref(localStorage.getItem('siblingData')) onMounted(() => { // Listen for changes to localStorage from other tabs/windows window.addEventListener('storage', (e) => { if (e.key === 'siblingData') { data.value = e.newValue } }) }) </script> <template> <p>{{ data }}</p> </template>This is best for non-sensitive, non-critical data since it’s persisted in the browser.
The right choice depends on your project scale: go with a shared composable or provide/inject for small apps, Pinia/Vuex for larger ones, and browser storage only for specific edge cases.
内容的提问来源于stack exchange,提问作者Ansh Sarwal

