Vue源码之event

421 阅读2分钟

编译阶段之parse

template

ast

id = 'app'的ast

id = 'demo'的ast

流程

总结

1.在闭合标签后执行closeElement,然后执行processElement执行processAttrs。

2.processAttrs获取到el.attrsList,遍历判断name是否是指令,是的话获取修饰符通过对象返回出来。

3.判断name为v-on进入逻辑执行,首先去掉@标签,然后调用addHandler向el中添加事件属性。

4.addHandler首先做了一些修饰符标记的替换,接着判断修饰符中有native那么给el添加的是nativeEvents属性否则是events属性。

5.接着设置一个newHandler对象,赋值value属性,还存在modifiers属性就添加进新对象中。

6.最后判断nativeEvents/events属性是否存在name这个事件,不存在设置属性为新对象,存在一个,设置为数组,存在两个删一个丢新的进去。

编译阶段之generate

code

id = 'app'的code

id = 'demo'的code

流程

总结

1.执行到generate阶段,执行genElement,执行genData,对于events和nativeEvents都是执行genHandlers函数传入个标识判断而已。

2.genHandlers首先根据标识确认输出nativeOn还是on属性名。

3.接着遍历传入的el.events或者el.nativeEvents,然后通过执行genHandler获取到handlerCode,接着和事件名name拼接起来,最后再和之前确认的属性名进行拼接。

原生DOM事件

  • create阶段

流程

总结

1.首先patch开始时会创建cbs对象和hooks,遍历Hooks为cbs添加hook属性为数组,接着继续遍历modules把modules定义相同hooks丢进数组中。最终返回cbs对象。

2.对于create除了按顺序执行存在data属性会调用invokeCreateHooks之外,在创建组件初始化完成时调用initComponent也会调用invokeCreateHooks。

3.invokeCreateHooks就是遍历调用cbs.create的函数,也就是执行updateDOMListeners,传入空vnode和vnode,

4.updateDOMListeners获取到vnode.data.on对象和获取vnode.elm节点,执行updateListeners,遍历on对象,cur=createFnInvoker返回的函数,把回调赋值给了invoker.fns,此函数是执行回调用的,然后调用add也就是调用addEventListener给节点添加事件和此函数,当点击触发时就执行此函数执行回调。

  • update阶段

流程

总结

1.对于update就是patch时不再是首次渲染,调用patchVnode时,如果vnode存在data对属性进行更新遍历调用cbs.update的函数,也就是updateDOMListeners,传入oldVnode和vnode,

2.updateDOMListeners获取到vnode.data.on对象和获取oldVnode.data.on对象,获取vnode.elm节点,执行updateListeners,遍历on对象,如果新旧的回调不同,把old.fns赋值为cur也就是新vnode的回调事件。

自定义事件作用在组件上

流程

总结

总结