this.$emit在Vue当中真的是子传父吗?
首先说结论-不是
源码
解析
- 首先我们可以看到$emit实际上是挂载到Vue实例原型上面的一个function
- $emit 实际上是往Vue的当前实例去派发一个事件
- 重要代码 let cbs = vm._events[event]-显然这一个和时间回调有关
- 它是如何被创建的呢
initEvents的时候进行创建
- 解析里面在vue实例上挂载了_events事件是一个对象
- 通过vm.$options._parentListeners挂载了父亲的监听器@fn
- 如果有监听器执行updateComponentListeners(vm, listeners)
updateComponentListeners
显然要创建一个事件监听机制-肯定要有回调函数
核心方法
createFnInvoker创建回调函数
createOnceHandler顾名思义 @click.once="add"
add方法好像是添加事件方法的样子
createFnInvoker
解析
简单来说就是创建了一个invoke函数
把我们的事件方法挂载到了invoker.fns return invoker
add方法
解析
- target就是vue实例调用$on方法
$on方法
- 在里面进行递归调用执行 然后push到对应的事件对象数组里面将fn方法
回头看$emit
里面进行遍历执行invokeWithErrorHandling
核心代码-给对应的事件方法传入参数并且进行执行
res = args ? handler.apply(context, args) : handler.call(context)
总结
- 很多时候网上广为流传的东西,不一定是对的还是需要自己-去阅读源码之后才能下定论。
- 时刻保持辩证的思想。