vue2和vue3 ,bus(事件总线)用于非父子组件传值问题

本文介绍Vue CLI 2 和 Vue CLI 3 中如何使用事件总线进行组件间通信。在Vue CLI 2中,通常通过main.js中的$bus实现;而在Vue CLI 3中,则推荐使用mitt库来简化事件处理流程。

vue-cli2

1.main.js
在这里插入图片描述
2.发送
在这里插入图片描述

3.接收
在这里插入图片描述

vue-cli3

1…安装mitt
yarn add mitt
2.在入口文件main.js中引入在这里插入图片描述
3.事件发送在这里插入图片描述
4.事件接收在这里插入图片描述

打印this.$bus
vue-cli2
在这里插入图片描述
在这里插入图片描述

vue-cli3
在这里插入图片描述

<think>嗯,用户问的是在Vue2中创建公共事件总线bus.js的最佳实践,以及文件的放置位置,还有父子组件通信的最佳实践。首先,我需要回忆一下Vue2事件总线相关知识。根据引用中的内容,事件总线是一个全局的Vue实例,用于组件间通信,特别是非父子组件的情况。用户提供的引用里提到,可以通过在main.js中定义Vue.prototype.$bus来创建全局事件总线,或者单独创建一个bus.js文件。 那问题来了,用户想知道bus.js应该放在哪个目录下。一般来说,Vue项目的结构通常有src目录,里面包含components、utils、plugins等文件夹。根据引用5中的例子,他们提到在utils文件夹下创建eventBus.js,然后通过import引入。所以可能最佳实践是将bus.js放在src/utils或src/plugins这样的目录里,这样方便管理维护。 接下来是父子组件通信的最佳实践。引用3详细说明了使用props$emit的方式,父组件通过props递数据给子组件,子组件通过$emit触发事件来向父组件通信。这种方式是Vue官方推荐的,适用于直接的父子关系。而事件总线更适合跨层级或兄弟组件之间的通信,比如引用2引用4提到的例子,使用$bus来避免多级递的繁琐。 用户可能还关心如何正确使用事件总线,比如避免$emit先于$on执行的问题,如引用4中提到的使用setTimeout或者确保$on在created生命周期钩子中注册。此外,还需要注意在组件销毁时移除事件监听,防止内存泄漏。比如在beforeDestroy钩子中使用$off来取消事件监听。 另外,用户提到最佳实践,可能需要对比事件总线Vuex的适用场景。引用4指出,如果场景不复杂,使用Vuex可能过于繁琐,这时事件总线更合适。但如果是大型项目,状态管理复杂,Vuex可能更适合。 总结一下,回答需要包括以下几点: 1. bus.js的创建方式,放在utils或plugins目录。 2. 父子组件通信使用props$emit。 3. 事件总线的正确使用,包括注册、触发、移除监听。 4. 注意事项,如异步处理、内存泄漏、适用场景。 5. 对比事件总线Vuex,给出最佳实践建议。 需要确保回答结构清晰,步骤明确,同时结合引用中的示例代码,提供具体的实现方法。可能还需要提到在Vue3事件总线的替代方案,比如使用mitt库,但用户问的是Vue2,所以这一点可以作为补充说明。</think>### Vue2 公共事件总线 bus.js 最佳实践及组件通信方案 #### 一、事件总线的创建与文件位置 1. **文件创建方式** ```javascript // src/utils/bus.js import Vue from &#39;vue&#39; export const bus = new Vue() ``` **推荐目录结构**: - 通用工具类文件建议放在 `src/utils` 目录 - 全局插件性质的文件可放在 `src/plugins` 目录 - 小型项目也可直接声明在 `main.js` 中: ```javascript // main.js Vue.prototype.$bus = new Vue() ``` 2. **组件中调用方式**: ```javascript import { bus } from &#39;@/utils/bus&#39; // 或直接通过 this.$bus 访问(需全局注册) ``` #### 二、父子组件通信最佳实践 1. **直接父子关系**: - 优先使用 `props/$emit` 机制(符合单向数据流原则) ```vue <!-- 父组件 --> <Child :data="list" @update="handleUpdate"/> <!-- 子组件 --> <script> this.$emit(&#39;update&#39;, newData) </script> ``` 2. **跨层级通信**: - 使用事件总线(需注意生命周期管理) ```javascript // 发送方 bus.$emit(&#39;global-event&#39;, payload) // 接收方 mounted() { bus.$on(&#39;global-event&#39;, this.handleEvent) }, beforeDestroy() { bus.$off(&#39;global-event&#39;, this.handleEvent) } ``` #### 三、关键注意事项(引用实践) 1. **时序问题解决方案**(引用[4]): ```javascript setTimeout(() => { this.$bus.$emit(&#39;event&#39;, data) }, 0) ``` 或确保接收方在 `created` 生命周期注册监听 2. **内存泄漏预防**: ```javascript // 组件销毁时移除监听(引用[4]) beforeDestroy() { this.$bus.$off(&#39;event&#39;) } ``` 3. **数据监听策略**(引用[4]): ```javascript watch: { receivedData: { handler(val) { // 处理数据变化 }, deep: true } } ``` #### 四、架构建议对比 | 方案 | 适用场景 | 优点 | 缺点 | |---------------|------------------------------|-----------------------|----------------------| | Props/$emit | 直接父子组件 | 官方推荐,类型检查 | 多级递繁琐 | | Event Bus | 跨层级/非父子组件 | 灵活轻量 | 需手动管理事件 | | Vuex | 大型应用/复杂状态管理 | 集中式状态管理 | 学习成本较高 | #### 五、进阶优化方案 1. **TypeScript 支持**: ```typescript // bus.ts import Vue from &#39;vue&#39; interface EventBus { $on: (event: string, callback: Function) => void $off: (event: string, callback?: Function) => void $emit: (event: string, ...args: any[]) => void } export const bus: EventBus = new Vue() ``` 2. **Vue3 兼容方案**: ```javascript // 使用 mitt 库替代 import mitt from &#39;mitt&#39; export const bus = mitt() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值