Vue2高级组件通信:5种非父子组件传值方案实战
核心价值: Vue2项目中经常遇到非父子组件需要通信的情况,本文将通过电商项目案例,详细讲解5种实用的组件通信方案及其适用场景。
1. 事件总线(Event Bus)
创建全局事件中心实现任意组件通信:
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
// 组件A发送事件
EventBus.$emit('cart-updated', {items: 5})
// 组件B接收事件
EventBus.$on('cart-updated', cart => {
this.cartCount = cart.items
})
2. Vuex状态管理
适合中大型项目的全局状态管理:
// store/modules/cart.js
const state = {
items: []
}
const mutations = {
ADD_ITEM(state, product) {
state.items.push(product)
}
}
// 组件中使用
this.$store.commit('cart/ADD_ITEM', product)
3. provide/inject
祖先组件向后代组件注入依赖:
// 祖先组件
export default {
provide() {
return {
appTheme: 'dark'
}
}
}
// 后代组件
export default {
inject: ['appTheme'],
created() {
console.log(this.appTheme) // 'dark'
}
}
4. $attrs/$listeners
跨级组件属性传递:
// 父组件
<child-component :title="pageTitle" @change="handleChange" />
// 中间组件
<grand-child v-bind="$attrs" v-on="$listeners" />
// 孙子组件
props: ['title'],
methods: {
triggerChange() {
this.$emit('change')
}
}
5. 本地存储通信
利用浏览器存储实现持久化通信:
// 组件A设置值
localStorage.setItem('user-preferences', JSON.stringify(settings))
// 组件B监听变化
window.addEventListener('storage', (e) => {
if(e.key === 'user-preferences') {
this.preferences = JSON.parse(e.newValue)
}
})
方案 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
事件总线 | 简单项目、临时通信 | 简单易用 | 不易维护 |
Vuex | 中大型项目 | 状态可追溯 | 概念较多 |
provide/inject | 深层嵌套组件 | 避免逐层传递 | 响应性有限 |
最佳实践建议:
- 简单项目优先使用事件总线
- 中大型项目必须使用Vuex
- 主题/配置类数据考虑provide/inject
- 需要持久化的数据使用本地存储
合理选择组件通信方案可以显著提升Vue项目的可维护性和开发效率,避免出现”面条式”代码。