Vue源码之 $emit
比如this.$emit(‘functionName‘,otherArguments),这里的this是一个Vue实例
$emit和v-on是一路的
组件节点上的v-on和真实节点上的v-on不一样,前者的v-on的方法key-value键值对会保存在组件的虚拟节点中,再传递给组件的parentListener属性,
在initEvents的时候,收集到vm._events数组中,(这个是在创建周期中提前处理的,而更新周期的处理在prepatch--->updateChildComponent方法中)
和真实节点的v-on对应的是组件节点上的v-on.native,这个的处理,在创建周期是先在生成虚拟节点vnode的时候把data.on = nativeOn
在patch()--->createComponent--->Vnode.data.hook.init之后的initComponent方法中的invokeCreateHooks,
把那七八个函数什么updateAttr,updateStyle,updateDOMListeners之类的,其中updateDOMListeners就是调用updateListeners方法,再调用真实节点的addEventListeners方法
真实的添加属性的绑定方法,注意上面说的initEvents也是调用updateListeners方法,区别就在于入栈的target和传入的add方法不同。
现在知道vm._events数组中,有functionName和其指向的,父组件中方法的引用。而且每次调用的this都是父组件实例,这是因为在initEvents之前的initMethods方法中,方法都被bind到了
父组件的vm上了:
vm[key] = typeof methods[key] !== ‘function‘ ? noop : bind(methods[key], vm);