最近小组有个关于vue源码分析的分享会,提前准备一下…

前言:
我们都知道Vue中父组件可以通过 props 向下传数据给子组件;子组件可以通过向$emit触发一个事件,在父组件中执行回调函数,从而实现子组件与父组件的通信,如下图:
在这里插入图片描述
从图可以看到,这种机制兄弟组件之间是通信不了的,假如不借助vuex等库,如何实现兄弟组件之间的通信?接下来说说事件总线。

事件总线的实现

举个例子,如图,建个vue的demo,包含父组件App、子组件Child1Child2
(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上。

Logo

前往低代码交流专区

更多推荐