使用 Vue.js 创建全局事件总线

Event Bus / 订阅发布(publish-subscribe)模式 虽然名声并不好,但当你需要让应用程序里完全不相干的分块互相通讯时,这仍是一个不错的方案。原本想找一些类库来帮助实现的,但想想 Vue 内建强大的 Event Bus 系统,要不我花点时间瞧一瞧?

尝试的结果还不错,内置 Vue Components 使用的事件系统 用来起来还是挺称手的。

初始化

首先你需要做的是创建事件总线并将其导出,以便其它模块可以使用或者监听它,这部分可能会比较麻烦。

import Vue from 'vue';
export const EventBus = new Vue();

但事实上它并不麻烦!
你需要做的只是引入 Vue 并导出它的一个实例(在这种情况下,我称它为 EventBus )。实质上它是一个不具备 DOM 的组件,它具有的仅仅只是它实例方法而已,因此它非常的轻便。

使用 Event Bus

现在我们已经创建了 Event Bus,接下来你需要做到的就是在你的组件中加载它,并且调用同一个方法,就如你在父子组件中互相传递消息一样。

发送 Event

假如你有一个组件,实现的功能就是当被点击时,通知整个应用其被点击的次数,你可以这样做 EventBus.emit(channel: string, payload1: any, …)

我使用了一个 单文件组件 ,但是你可以使用其他的组件方法。

<template>
  <div class="pleeease-click-me" @click="emitGlobalClickEvent()"></div>
</template>

<script>
// 导入我们刚刚创建的 EventBus
import { EventBus } from './event-bus.js';

export default {
  data() {
    return {
      clickCount: 0
    }
  },

  methods: {
    emitGlobalClickEvent() {
      this.clickCount++;
      // Send the event on a channel (i-got-clicked) with a payload (the click count.)
      EventBus.$emit('i-got-clicked', this.clickCount);
    }
  }
}
</script>

接收 Events

现在当我们的 PleaseClickMe.vue 被点击时候,只要导入了 EventBus 并且使用 EventBus.$on(channel: string, callback(payload1,…)) 监听 i-got-clicked 频道的话:

// Import the EventBus.
import { EventBus } from './event-bus.js';

// Listen for the i-got-clicked event and its payload.
EventBus.$on('i-got-clicked', clickCount => {
  console.log(`Oh, that's nice. It's gotten ${clickCount} clicks! :)`)
});

如果你只想监听一次事件的发生,可以使用 EventBus.$once(channel: string, callback(payload1,…))

移除事件监听者

你可以使用以下的方法来移除对 PleaseClickMe.vue 点击次数的监听:

// 导入我们刚刚创建的 EventBus
import { EventBus } from './event-bus.js';

// 事件监听函数
const clickHandler = function(clickCount) {
  console.log(`Oh, that's nice. It's gotten ${clickCount} clicks! :)`)
}

// 开始监听事件
EventBus.$on('i-got-clicked', clickHandler);

// 停止监听
EventBus.$off('i-got-clicked', clickHandler);

你也可以使用 EventBus.$off(‘i-got-clicked’) 来移除应用内所有对此事件的监听。

你也可以直接调用 EventBus.$off() 来移除所有事件频道,注意不需要添加任何参数。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://alligator.io/vuejs/global-event-...

译文地址:https://learnku.com/vuejs/t/23292/creati...

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!