0%

Vue2.x的事件中心

Vue中通过EventBus事件中心进行兄弟节点之间的通信,是一个非常经典的发布订阅模式实现。

前置准备

往Vue实例上添加一个_events属性,属性值是一个对象,用于以键值对的方式,分别存储事件名称,以及存储事件回调函数的数组。

$on、$once、$emit、$off方法是定义在Vue原型上的,所有的Vue实例都可以调用这些方法。

事件中心要运转起来,必须要基于同一个实例来调用这些方法,因为只有这样事件的存储空间才会被共用,事件的发布和订阅才能被串起来。在Vue中使用事件中心的时候,可以全局定义一个Vue实例,专门用于组件通信。

$on

$on方法接收两个参数,第一个参数可能是字符串类型的事件名和数组类型事件名数组,第二个参数是回调函数。

这里用到了递归,如果参数的第一项是数组,就遍历数组,将数组项作为第一个参数,第二个参数不变,递归执行$on方法。直到第一个参数是一个字符串了,就可以接着执行订阅事件的逻辑。

接下来判断当前_events对象里,$on方法的第一个参数作为key,所对应的值是否存在。

  1. 如果不存在,则先创建一个空数组,然后再往数组中添加回调函数;
  2. 如果存在,则说明值已经是一个数组类型了,直接往数组中添加回调函数。

$once

$once方法接收两个参数,第一个参数是字符串类型的事件名,第二个参数是回调函数。

内部执行的就是on方法,并且当回调函数执行一次后,再通过off方法移除事件的回调,确保回调函数只执行一次。

在once方法中新创建一个回调函数,作为on方法事件的回调,在新回调函数中执行off方法移除事件的回调,那么新回调函数就是只会被执行一次,在里面执行once的第二个参数就可以了。

$emit

$emit方法接收一个参数,是一个字符串类型的事件名。

根据事件名找到事件名对应的所有的回调函数,然后执行所有的回调函数。

$off

$off方法接收参数是不固定个数的(0、1或2),用于移除事件回调。

  1. $off():将_events对象赋值为空对象;
  2. $off([event, …], fn):这里也用到了递归,最后执行off(event, fn),一个一个执行移除指定事件名event和指定fn;
  3. $off(event, fn):用于移除指定事件名event和指定fn;
  4. $off(event):用于移除指定事件名event对应所有的fn。