Vue中事件发射emit以及事件响应on的实现

事件机制是Vue中重要的通信机制,这里看下源码简单说明下Vue事件emit和on的实现:

 $on和$emit函数的实现:


```Vue.prototype.$on = function (event: string | Array, fn: Function): Component {

    const vm: Component = this

    if (Array.isArray(event)) {

      for (let i = 0, l = event.length; i < l; i++) {

        this.$on(event[i], fn)

      }

    } else {

      (vm._events[event] || (vm._events[event] = [])).push(fn)

      // optimize hook:event cost by using a boolean flag marked at registration

      // instead of a hash lookup

      if (hookRE.test(event)) {

        vm._hasHookEvent = true

      }

    }

    return vm

  }

```

很简单,就是创建一个event数组成员,保存定义的事件名称和处理函数,数组的下标就是时间的名称,value是函数引用。但是要注意,时间都是保存在当前对象上的,比如new了一个组件的实例A,在A上注册的事件,是在A的_event数组中保存。

```Vue.prototype.$emit = function (event: string): Component {

    const vm: Component = this

    ... 省略不重要代码

    let cbs = vm._events[event]

    if (cbs) {

      cbs = cbs.length > 1 ? toArray(cbs) : cbs

      const args = toArray(arguments, 1)

      for (let i = 0, l = cbs.length; i < l; i++) {

        try {

          cbs[i].apply(vm, args)

        } catch (e) {

          handleError(e, vm, `event handler for "${event}"`)

        }

      }

    }

    return vm

  }

}

```

这个函数也很简单,emit直接调用了注册在本组件上的响应函数。**但是,这是问题的全部么?**,比如组件B上emit了一个事件,而这个事件注册在组件A上,这时候,必须执行A上的emit才可以完成整个事件流程,那这又是在哪里实现的呢?

仔细回忆了下emit和on的使用:

1. 父子组件通信,子组件可以emit然后修改父组件的data来实现通讯,这里on和emit都在子组件上,注意不是子组件emit父组件on,而是都在子组件上。

2. 组件之间通信,使用专门的通信组件bus,此时,on和emit都在Vue的实例bus上调用。

所以emit和on都是在同一个实例上调用的,上面的代码**That’s all**。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容