早上好!继续学习Vue源码~这次我们来学习 event 事件。
源码简析
其实看了前两篇的同学已经知道源码怎么找了,这里再提一下。
先找到Vue核心源码index方法 src/core/instance/index.js
1 | function Vue (options) { |
index方法中定义了一个Vue的构造函数执行 _init
方法初始化,然后执行了多个 xxxMixin
方法,这些方法是为Vue 的构造函数定义各类属性的。比如我们今天关注的事件,Vue的几个事件方法都是在 eventsMixin
中定义的。
1 | export function eventsMixin (Vue: Class<Component>) { |
另外要注意的是,initMixin
方法中定义了Vue的初始化方法 _init
,该方法中对Vue各类属性进行了初始化。
1 | export function initMixin (Vue: Class<Component>) { |
所以,在本篇博客中只需要关注 initEvents
和 eventsMixin
方法即可
initEvents
初始化过程很简单,清空数据,并初始化连接父级的事件。
1 | // src/core/instance/events.js |
我深入看了下 updateComponentListeners
方法,最终走到了 src/core/vdom/helpers/update-listeners.js
的 updateListeners
方法中,因为并没有传 oldOn
参数,所以我简化了下代码,简化代码如下:
1 | // src/core/vdom/helpers/update-listeners.js |
其中这个add方法如下:
1 | // src/core/instance/events.js |
整理下来就是将父级的事件定义到当前vm中。
$on
监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。
代码如下
1 | // src/core/instance/events.js |
如果 event 是数组则遍历执行 $on 方法(2.2.0+ 中支持);
否则 向 vm._events[event] 中传递回调函数 fn,这里既然 vm._events[event] 是一个数组,那么我猜想一个 event 可以执行多个回调函数咯?
如果是 event 字符串中有 hook:
,修改 vm._hasHookEvent
的状态。如果 _hasHookEvent
为 true,那么在触发各类生命周期钩子的时候会触发如 hook:created
事件,这只是一种优化方式,与我们主题关系不大,具体请看代码~
1 | // src/core/instance/lifecycle.js |
$once
监听一个自定义事件,但是只触发一次,在第一次触发之后移除监听器。
代码
1 | // src/core/instance/events.js |
这个就简单了,定义一个 $on 事件监听,回调函数中使用 $off 方法取消事件监听,并执行回调函数。
$off
移除自定义事件监听器。
- 如果没有提供参数,则移除所有的事件监听器;
- 如果只提供了事件,则移除该事件所有的监听器;
- 如果同时提供了事件与回调,则只移除这个回调的监听器。
代码如下,分析见注释。
1 | // src/core/instance/events.js |
$emit
触发当前实例上的事件。附加参数都会传给监听器回调。
代码
1 | // src/core/instance/events.js |
代码分析:首先获取 vm._events[event] ,之前我们说过这玩意是个数组;如果有这个事件监听器,从第二个参数开始获取作为触发方法的传参 args,遍历事件监听器数组传参执行回调函数。
最后
就这么多啦~其实事件还是很简单的。明后天研究研究渲染这个难点!我们后天见!
Vue.js学习系列
鉴于前端知识碎片化严重,我希望能够系统化的整理出一套关于Vue的学习系列博客。
Vue.js学习系列项目地址
本文源码已收入到GitHub中,以供参考,当然能留下一个star更好啦^-^。
https://github.com/violetjack/VueStudyDemos
关于作者
VioletJack,高效学习前端工程师,喜欢研究提高效率的方法,也专注于Vue前端相关知识的学习、整理。
欢迎关注、点赞、评论留言~我将持续产出Vue相关优质内容。
新浪微博: http://weibo.com/u/2640909603
掘金:https://gold.xitu.io/user/571d953d39b0570068145cd1
CSDN: http://blog.csdn.net/violetjack0808
简书: http://www.jianshu.com/users/54ae4af3a98d/latest_articles
Github: https://github.com/violetjack