美文网首页
Vue中事件发射emit以及事件响应on的实现

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

作者: ttabc | 来源:发表于2018-04-26 14:37 被阅读0次

事件机制是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**。

相关文章

网友评论

      本文标题:Vue中事件发射emit以及事件响应on的实现

      本文链接:https://www.haomeiwen.com/subject/yaoplftx.html