![d37a6763ec695b830518ddbb3c53b3b8.png](https://i-blog.csdnimg.cn/blog_migrate/6f6545630efaeb4e52b117a78c8c30d0.jpeg)
专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧
研究基于 Vue版本【2.5.17】
Vue 事件是我最感兴趣的东西之一,一直想研究玩玩
特别是组件自定义事件,很想知道,给子组件绑定自定义事件,子组件是怎么触发的 巴拉巴拉的
开始正文了
在 Vue 中,事件大概分为 4 种
1、自定义事件
2、DOM 事件
3、组件DOM 事件
4、组件自定义事件
然后再细分,就只有两种
1、自定义事件
2、DOM 事件
下面就来粗略说一下事件
如果你觉得排版难看,请点击下面链接
【Vue原理】Event - 白话版mp.weixin.qq.com![2c74d5aa6ac68dadbe6c3cf56f63b120.png](https://i-blog.csdnimg.cn/blog_migrate/bbd6417b860e69728270def8da1cb9e4.jpeg)
或者 关注公众号【神仙朱】吧
![f6184000282e8f16f27df002bc53f1a5.png](https://i-blog.csdnimg.cn/blog_migrate/ab6d12a5ba26b51e98c8a09bb50db07a.png)
自定义事件
自定义事件 是使用观察者模式建立起来的一种事件机制
分为 个人使用 和 组件使用
自定义事件主要由下面两部分构成
1、有事件存储器
2、绑定事件,触发事件,解绑事件三个函数
在 Vue 中,每个实例都会添加一个属性_events,用来存放本实例上注册的自定义事件
![63c895cc53435055866dded214bdab82.png](https://i-blog.csdnimg.cn/blog_migrate/45598b899ba302ba4aaf288a7d0469fb.jpeg)
_events 就是 事件存储器,是一个对象
属性名是 事件名,属性值是事件回调
个人调用自定义事件
我也经常在项目中使用到 自定义事件,像下面这样
![49f52c26739956962822e007c894c403.png](https://i-blog.csdnimg.cn/blog_migrate/91eefbd4d0e6bf8162b63fe8b4a5ed76.jpeg)
没错,$on 就是注册事件,$emit 是 触发事件,$off 就是 解绑事件
在哪个实例上注册的事件,事件就属于哪个实例,正常情况下,你是不可能能触发别的实例上的事件的
而给组件绑定自定义事件 是怎么样的呢?
![7adb1666973a7856453dee680041e624.png](https://i-blog.csdnimg.cn/blog_migrate/34293f99e39e5a1af719ee97e38609d5.jpeg)
结果也是一样的,前面的解析处理可以不管,最后同样是使用内置的 $on 方法去注册事件
而这个事件依然是属于子组件的,存放在 子组件的 _events 中
![f4001fae11ed3e3cae9e967d8ae0ba2a.png](https://i-blog.csdnimg.cn/blog_migrate/281a30a5f81bec1f70242462526a5a63.jpeg)
所以你可以在子组件中,使用 this.$emit 触发这个事件
DOM 事件
DOM 事件,最后就是直接给 DOM 绑定事件
使用 addEventListeners 绑定事件,没有做任何兼容处理,灰常简单
绑定事件,是在DOM 创建之后,插入页面之前
1、普通标签绑定事件
![452c67465a4b8f37e88dfd0407114af8.png](https://i-blog.csdnimg.cn/blog_migrate/ac83a985a90216990685958446a5cf4a.jpeg)
很简单,普通 addEventListener 绑定DOM事件就完事了
事件会被保存在这个节点解析成的 vnode 中,就是 vm._vnode
![5ee0fffd9dd26ada1648478ee9a18442.png](https://i-blog.csdnimg.cn/blog_migrate/9b3bfd05f820205054decd939b8c1658.jpeg)
2、组件绑定DOM 事件
如果要给组件绑定原生DOM 事件,需要加上 native 这个修饰器
![7e5a27937a8ea70419109dc50ecf051f.png](https://i-blog.csdnimg.cn/blog_migrate/c4f51bf5e9eb2fd3aaea01162d452a04.jpeg)
组件绑定的DOM 事件,在父实例解析完毕开始挂载时,遇到子元素是组件,然后去解析组件内部并生成DOM之后才 addEventListener 绑定
绑定的原生事件,会被存放在组件的外壳节点上 vm.$vnode
![1e544722bb9308e09e635dadc695b6e6.png](https://i-blog.csdnimg.cn/blog_migrate/e346dc45bec214cfcd7d0ea207baad5b.jpeg)
还有,你可能会想,如果这样绑定DOM事件会怎么样?
![cf3207d718a517b33b3d38e8ce914ec1.png](https://i-blog.csdnimg.cn/blog_migrate/d5228f050dab1353128e144d3d19479d.jpeg)
问得好,这样并不会绑定DOM事件,而是给组件绑定自定义事件,最后是会存在 子组件的 _events 中的,并不会绑定DOM事件
![5861b22b0383b8fc3a0ef9a9622cdaf8.png](https://i-blog.csdnimg.cn/blog_migrate/557fe00a0f08185604be2be671ce564d.jpeg)
然后可以在子组件中用 this.$emit("click") 去触发这个父组件绑定的这个click