[Vue源码分析]自定义事件原理及事件总线的实现
最近小组有个关于vue源码分析的分享会,提前准备一下…前言:我们都知道Vue中父组件可以通过 props 向下传数据给子组件;子组件可以通过向$emit触发一个事件,在父组件中执行回调函数,从而实现子组件与父组件的通信,如下图:从图可以看到,这种机制兄弟组件之间是通信不了的,假如不借助vuex等库,如何实现兄弟组件之间的通信?接下来说说事件总线。事件总线的实现举个例子,如图,建个vue...
最近小组有个关于vue源码分析的分享会,提前准备一下…
前言:
我们都知道Vue中父组件可以通过 props 向下传数据给子组件;子组件可以通过向$emit触发一个事件,在父组件中执行回调函数,从而实现子组件与父组件的通信,如下图:
从图可以看到,这种机制兄弟组件之间是通信不了的,假如不借助vuex等库,如何实现兄弟组件之间的通信?接下来说说事件总线。
事件总线的实现
举个例子,如图,建个vue的demo,包含父组件App
、子组件Child1
及Child2
。
(1)main.js
如图,Vue的原型上定义一个$EventBus
,这个$EventBus
是一个vue的实例。
(2)App.vue
(3)Child1.vue
(2)Child2.vue
打开浏览器,可以看到如图结果:
以上例子比较简单,就不解释了,可以看到例子就没有借助vuex,便实现了兄弟组件之间的通信,这是因为我们在Vue原型上定义了一个全局的$EventsBus
,各种组件都在共用这个全局的对象,理解其中的原理,首先要对自定义事件做一个分析,接下看看Vue自定义事件实现的相关源码。
Vue自定义事件实现原理分析
在vue实例化的时候,会进行很多初始化操作,其中包括eventsMixin
这个方法,如图:
这个方法主要包含四个方法,如图:
(1)Vue.prototype.$on
可以看到,这个函数首先判断传进来的event
是不是一个数组,如果是数组,循环调用$on
把事件及回调函数按照事件的名称event
把回调函数 fn 存储起来,如代码中的vm._events[event].push(fn)
。
(2)Vue.prototype.$emit
当执行 vm.$emit(event)
的时候,根据事件名event
找到所有的回调函数,如代码中的var cbs = vm._events[event]
,然后遍历执行所有的回调函数。
需要注意的是,这里用到了一个toArray(arguments, 1)
的方法,是因为第二个开始才是传递的参数,所以需要截取出来,如图:
题外:有兴趣可以去了解一下Array.prototype.slice.call()
这个方法
(3)vm.$off、vm. $once
这两个方法比较简单,就不截图了,有兴趣可以自行去看看。大致是执行vm.$off(event,fn)
时会移除指定的事件及回调函数 ;当执行 vm.$once(event,fn)
时,执行的是 vm.$on
,但回调函数执行一次后会通过vm.$off
移除事件的回调,这样就确保了回调函数只执行一次。
总结
所自定义的事件添加和删除用的就是上边说的几个方法。子组件中通过$emit
派发事件,父组件中通过$on
执行回调,进而实现子组件与父组件的通信。事件总线之所以能实现兄弟组件的通信,是因为$emit
及$on
都定义到了一个全局的$EventBus
上。
更多推荐
所有评论(0)