本文翻译自 Creating a Global Event Bus with Vue.js

尽管 EventBus 或发布-订阅模式的开发方式有时备受诟病,但对于应用程序中联系性低的部分来说,它的确是一个极好的通信方式。但是与其引用第三方库来增大我们项目的体积,何不尝试一下 Vue 内置的、强大的 event bus 呢?

事实证明,Vue 组件中所使用的事件系统 同样可以脱离开来单独使用。

初始化

你需要做的第一件事,是创建一个 event bus 并将它导出到某个地方,以便其他模块或组件使用。或许这一部分可能会有点棘手?

// event-bus.js
import Vue from 'vue';
export const EventBus = new Vue();

然而这非常简单。你只需要将 Vue 引入并导出它的一个示例(在这个例子中,我把它命名为 EventBus)。你实际上得到的是一个和 DOM 以及应用中其他部分完全分离的组件。它只存在一些实例方法,所以非常地轻量。

使用 Event Bus

现在你已经创建好了 event bus,你只需要做的是将它引入到组件中,并在父子组件传递消息进行通信时调用相同的方法。

发送事件

假设你有一个这样的组件:当它被点击的时候,需要将它被点击的次数通知到整个应用中。你可以使用这个方法来实现:EventBus.emit(channel: string, payload1: any, …)

这里使用的是 Vue SFC,但是你可以使用任何方法来创建你想要的组件。

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

<script>
// Import the EventBus we just created.
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>

接收事件

现在,你可以在应用中的任何地方引入 EventBus 并通过这个方法来监听 PleaseClickMe.vue 发布的频道 i-got-clickedEventBus.$on(channel: string, callback(payload1,…))

// the-kindly-script.js
// 引入 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 发出的事件,你可以像这样从对应的频道中注销他们的 handle 方法。

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

// The event handler function.
const clickHandler = function(clickCount) {
  console.log(`Oh, that's nice. It's gotten ${clickCount} clicks! :)`)
}

// Listen to the event.
EventBus.$on('i-got-clicked', clickHandler);

// Stop listening.
EventBus.$off('i-got-clicked', clickHandler);

你也可以通过这个方法来移除某一个事件的所有监听器:EventBus.$off(‘i-got-clicked’)
如果你需要删除 EventBus 中的所有频道的所有监听器,你可以直接使用 EventBus.$off()

文章来源于腾讯云开发者社区,点击查看原文