vue.js源码解读系列 - Vue的自定义事件机制

最近在解析vue源码,后期会不断更新有兴趣的能够关注个人博客vue

关注个人博客:zane的我的博客
git


先看一波使用方式:github

vm.$on 有两个参数,第一个参数能够是字符串也能够是数组,第二个是回调函数

  • 监听当前实例上的自定义事件。事件能够由vm.$emit触发。回调函数会接收全部传入事件触发函数的额外参数json

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 有两个参数,第一个参数能够是字符串也能够是数组,第二个是回调函数

  • 若是没有提供参数,则移除全部的事件监听器;
  • 若是只提供了事件,则移除该事件全部的监听器;数组

  • 若是同时提供了事件与回调,则只移除这个回调的监听器。bash

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中

一、初始化事件,在vm下挂载_events属性对象,全部添加的自定义事件都会存放其中


二、$on事件的实现


根据以上分析能够看出 vm._events 的结构为:app

vm._events={
    'test':[fn,fn...],
    'test1':[fn,fn...]
}复制代码


三、$once事件的实现


根据分析得出 $once绑定的事件 vm.events 的结构为:函数

vm._events={
    'oncetest':[ 
          function on(){
              vm.$off(event,on)
              fn.apply(vm,arguments)
          } ,
          ...
     ]
}复制代码


四、$off事件的实现


一一的实现了下面的这三点:this

  • 若是没有提供参数,则移除全部的事件监听器;spa

  • 若是只提供了事件,则移除该事件全部的监听器;

  • 若是同时提供了事件与回调,则只移除这个回调的监听器。


五、$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的自定义事件机制

相关文章
相关标签/搜索