Vue2-Vue3组件间通信-EventBus方式-函数封装

309 篇文章 78 订阅

Vue3中采用EventBus方式进行组件间通信与Vue2有一定区别

1.创建EventBus

在Vue2中,我们可以在main.js中创建一个全局的EventBus,代码如下:

// EventBus.js
import Vue from 'vue'
const EventBus = new Vue()
export default EventBus

// main.js
import EventBus from './EventBus'
Vue.prototype.$bus = EventBus

在Vue3中,我们需要使用createApp来创建Vue实例,并使用provide和inject来创建全局的EventBus,代码如下:

// EventBus.js
import { createApp } from 'vue'
const app = createApp({})
const EventBus = app.provide('EventBus', new app())
export default EventBus

// main.js
import EventBus from './EventBus'
createApp(App).use(EventBus).mount('#app')


-----------------
// 在 main.js 或入口文件中
import { createApp, provide } from 'vue';
import App from './App.vue';

const app = createApp(App);
const eventBus = createApp({});

// 将 eventBus 实例作为提供者提供给子组件
app.provide('eventBus', eventBus);

app.mount('#app');

2.使用EventBus进行通信

在Vue2中,我们可以通过$emit和$on方法来进行通信,代码如下:

// 发送通信
this.$emit('event', data)

// 接收通信
this.$on('event', (data) => {
  console.log(data)
})

// 销毁
this.$off('event')

在Vue3中,我们可以通过$emit和$on方法来进行通信,但是需要在组件中使用AppContext来获取EventBus,代码如下:

// 发送通信
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.emit('event', data)

// 接收通信
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.on('event', (data) => {
  console.log(data)
})

//  销毁
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.off('event')


-------------------
import { inject } from 'vue';

export default {
  // ...
  created() {
    const eventBus = inject('eventBus');
    // 使用 eventBus 进行事件的发布和订阅
  },
  // ...
}

总的来说,Vue3与Vue2在EventBus方式上的区别不大,只是在创建全局EventBus的方式上有所不同,但是使用起来差异较大,需要根据实际情况进行选择。


封装EventBus.js

类方式 

class Event {
  constructor() {
    this.queue = {};
    this.onceQueue = {};
  }

  $on(name, callback) {
    this.queue[name] = this.queue[name] || [];
    this.queue[name].push(callback);
  }

  $once(name, callback) {
    this.onceQueue[name] = this.onceQueue[name] || [];
    this.onceQueue[name].push(callback);
  }

  $off(name, callback) {
    if (callback) {
      if (this.queue[name]) {
        for (var i = 0; i < this.queue[name].length; i++) {
          if (this.queue[name][i] === callback) {
            this.queue[name].splice(i, 1);
            break;
          }
        }
      }
    } else {
      delete this.queue[name];
    }
  }

  $emit(name, data) {
    if (this.queue[name]) {
      this.queue[name].forEach(function (callback) {
        callback(data);
      });
    }
    if (this.onceQueue[name]) {
      this.onceQueue[name].forEach(function (callback) {
        callback(data);
      });
      delete this.onceQueue[name];
    }
  }
}

export default new Event();



使用 

import Bus from '@/utils/EventBus';
Bus.$on('test', (data) => {})
Bus.$emit('close')
beforeUnmount() {
    Bus.$off('test', fun)
}

构造函数方式

function E() { }

// 函数E的原型对象
E.prototype = {
    // on方法:接受订阅名,订阅函数,上下文对象
    on: function (name, callback, context) {
        // 初始化e仓库
        var e = this.e || (this.e = {})
            // 收集订阅函数
            // 包装为对象,收集订阅函数与上下文对象
            ; (e[name] || (e[name] = [])).push({
                fn: callback,
                context
            })
        // 返回实例对象
        return this
    },
    // once函数:接收订阅名,订阅函数,上下文对象
    // 与on的区别是:once函数收集只执行一遍的订阅函数
    once: function (name, callback, context) {
        let self = this
        // 包装对象,用于自定义执行逻辑(删除操作)
        function listener() {
            self.off(name, listener)
            callback.apply(context, arguments)
        }
        // 保存原始函数
        listener._ = callback
        // 使用on收集自定义后的函数
        // 执行on方法会返回this,所以once函数内不需要返回this
        return this.on(name, listener, context)
    },
    // emit方法用于触发订阅函数:接收订阅名称
    emit: function (name) {
        // 收集参数
        let args = [].slice.call(arguments, 1)
        // 收集订阅函数数组
        let events = ((this.e || (this.e = {}))[name] || []).slice()

        let i = 0
        let len = events.length
        // 循环执行订阅函数
        for (; i < len; i++) {
            // 使用apply调用函数并绑定this
            events[i].fn.apply(events[i].context, args)
        }
        // 返回this实例
        return this
    },
    // off用于删除订阅函数:接收订阅名和订阅函数
    off: function (name, callback) {
        let e = this.e || (this.e = {})
        // 获取订阅名称对应的数组
        let events = e[name]
        let liveEvents = []
        // 处理函数数组&传入的订阅函数是否都存在?
        if (events && callback) {
            // 循环遍历,过滤操作
            for (let i = 0, len = events.length; i < len; i++) {
                // 判断数组中的订阅函数是否与传入的订阅函数相等?
                // 使用once创建的函数取_属性中的原始函数进行对比
                if (events[i].fn !== callback && events[i].fn._ !== callback) {
                    liveEvents.push(events[i])
                }
            }
        }
        // 重置订阅名结果数组
        (liveEvents.length) ? e[name] = liveEvents : delete e[name]
        // 返回实例this
        return this
    }
}

export default {
    $on: (...args) => E.prototype.on(...args),
    $once: (...args) => E.prototype.once(...args),
    $off: (...args) => E.prototype.off(...args),
    $emit: (...args) => E.prototype.emit(...args)
}

使用 

import Bus from "@/utils/EventBus2";
Bus.$on('test', (data) => {})
Bus.$emit('close')
beforeUnmount() {
    Bus.$off('test', fun)
}

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
Vue.js 中的 EventBus 是一种用于在组件之间进行通信的机制。它允许你在不同的组件中发送和接收事件,以实现组件之间的解耦和交互。 在 Vue.js 中使用 EventBus,你需要创建一个中央事件总线(EventBus)实例,它可以作为一个简单的 Vue 实例来充当事件中心。你可以在任何组件中引用该实例,并使用它来发送和接收事件。 以下是一个简单的 EventBus 的实现示例: 1. 创建 EventBus 实例: ```javascript // EventBus.js import Vue from 'vue'; export const EventBus = new Vue(); ``` 2. 在发送事件的组件中使用 EventBus: ```javascript // ComponentA.vue import { EventBus } from './EventBus.js'; export default { methods: { sendData() { // 发送名为 'eventA' 的事件,并传递数据 EventBus.$emit('eventA', data); } } } ``` 3. 在接收事件的组件中使用 EventBus: ```javascript // ComponentB.vue import { EventBus } from './EventBus.js'; export default { created() { // 监听名为 'eventA' 的事件 EventBus.$on('eventA', this.handleEventA); }, methods: { handleEventA(data) { // 处理接收到的事件和数据 console.log('Received eventA:', data); } } } ``` 通过上述步骤,ComponentA 可以通过发送名为 'eventA' 的事件,并传递数据,而 ComponentB 则可以通过监听 'eventA' 事件来接收并处理数据。这样,两个组件之间就可以进行通信了。 注意:为了避免内存泄漏,记得在组件销毁前取消对事件的监听,即在组件的 `beforeDestroy` 生命周期钩子中使用 `EventBus.$off('eventA')` 来取消监听。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackieDYH

谢谢您嘞!我会继续加油地

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值