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);

相关推荐