Open libin1991 opened 6 years ago
最近在解析vue源码,后期会不断更新有兴趣的可以关注我的博客
关注我的博客:zane的个人博客
先看一波使用方式:
监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数
vm.$on('test', function (msg) { console.log(msg) }) vm.$on(['test1','test2'], function (msg) { console.log(msg) })
vm.$once('testonce', function (msg) { console.log(msg) })
如果只提供了事件,则移除该事件所有的监听器;
如果同时提供了事件与回调,则只移除这个回调的监听器。
vm.$off() vm.$off('test') vm.$off('test1', function (msg) { console.log(msg) }) vm.$off(['test1','test2'], function (msg) { console.log(msg) })
vm.$emit('test', '触发自定义事件')
根据以上分析可以看出 vm._events 的结构为:
vm._events={ 'test':[fn,fn...], 'test1':[fn,fn...] }
根据分析得出 $once绑定的事件 vm.events 的结构为:
vm._events={ 'oncetest':[ function on(){ vm.$off(event,on) fn.apply(vm,arguments) } , ... ] }
一一的实现了下面的这三点:
如果没有提供参数,则移除所有的事件监听器;
白话描述:匹配到json中相关key值的value,这个value先转换成真正的数组,再循环遍历数组,传入给的参数执行数组中的每个函数。
最终的vm._events可以是这样的值:
vm._events={ 'test1':[fn,fn,fn], 'test2':[fn], 'oncetest':[ function on(){ vm.$off(event,on) fn.apply(vm,arguments) }, ... ], ... }
vue中自定义事件的主要作用是组件间的通信,因为_events对象最终挂载在Vue的实例上,因此每个组件都能够访问到vm._events的值,也能向其中push相关的订阅函数。
最典型的用法就是vue组件间的组件通信,父组件使用 :foo.sync , 子组件使用 this.$emit('update:foo', option) 进行双向通信,如果你有看过vue的源码就会发现实际上,:foo.sync 最终会绑定一个 'update:foo' 的事件。
<comp :foo.sync="bar"></comp> 会被拓展为 <comp :foo="bar" @update:foo="val => bar = val"></comp>
原文地址:vue.js源码解读系列 - Vue的自定义事件机制
最近在解析vue源码,后期会不断更新有兴趣的可以关注我的博客
关注我的博客:zane的个人博客
先看一波使用方式:
vm.$on 有两个参数,第一个参数可以是字符串也可以是数组,第二个是回调函数
监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数
vm.$on('test', function (msg) { console.log(msg) }) vm.$on(['test1','test2'], function (msg) { console.log(msg) })
vm.$once 有两个参数,第一个是时间名称只能是字符串,第二个是回调函数
vm.$once('testonce', function (msg) { console.log(msg) })
vm.$off 有两个参数,第一个参数可以是字符串也可以是数组,第二个是回调函数
如果只提供了事件,则移除该事件所有的监听器;
如果同时提供了事件与回调,则只移除这个回调的监听器。
vm.$off() vm.$off('test') vm.$off('test1', function (msg) { console.log(msg) }) vm.$off(['test1','test2'], function (msg) { console.log(msg) })
vm.$emit 有两个参数,第一个参数触发的事件名,第二参数传递的参数
vm.$emit('test', '触发自定义事件')
下面从源码来看其实现,vue的自定义事件功能实现在 core/instance/events.js中
1、初始化事件,在vm下挂载_events属性对象,所有添加的自定义事件都会存放其中
2、$on事件的实现
根据以上分析可以看出 vm._events 的结构为:
vm._events={ 'test':[fn,fn...], 'test1':[fn,fn...] }
3、$once事件的实现
根据分析得出 $once绑定的事件 vm.events 的结构为:
vm._events={ 'oncetest':[ function on(){ vm.$off(event,on) fn.apply(vm,arguments) } , ... ] }
4、$off事件的实现
一一的实现了下面的这三点:
如果没有提供参数,则移除所有的事件监听器;
如果只提供了事件,则移除该事件所有的监听器;
如果同时提供了事件与回调,则只移除这个回调的监听器。
5、$emit事件的实现
白话描述:匹配到json中相关key值的value,这个value先转换成真正的数组,再循环遍历数组,传入给的参数执行数组中的每个函数。
总结:
整个自定义事件就是在vm下挂载一个_events的Object对象,可以理解为一个json,其中json的key值就是自定义事件的名称,一个key值可能对应着多个自定义事件,因此json中每个key对应的value都是一个数组,每次执行事件监听都会向数组中push相关的函数,最终通过$emit函数传入的参数,匹配到json中相应的key,val值,从而使用给定的参数执行数组中的函数。
最终的vm._events可以是这样的值:
vm._events={ 'test1':[fn,fn,fn], 'test2':[fn], 'oncetest':[ function on(){ vm.$off(event,on) fn.apply(vm,arguments) }, ... ], ... }
vue中自定义事件的主要作用是组件间的通信,因为_events对象最终挂载在Vue的实例上,因此每个组件都能够访问到vm._events的值,也能向其中push相关的订阅函数。
最典型的用法就是vue组件间的组件通信,父组件使用 :foo.sync , 子组件使用 this.$emit('update:foo', option) 进行双向通信,如果你有看过vue的源码就会发现实际上,:foo.sync 最终会绑定一个 'update:foo' 的事件。
<comp :foo.sync="bar"></comp> 会被拓展为 <comp :foo="bar" @update:foo="val => bar = val"></comp>
关注我的博客:zane的个人博客
原文地址:vue.js源码解读系列 - Vue的自定义事件机制