VuePatch源码学习笔记

Vue Patch

VNode 了解

createPatchFunction


文件路径:~/github/vuejs/vue/src/core/vdom/patch.js

笔记:

这个文件中会创建一个patch的函数,传入nodeOps以及modules

关于nodeOps

关于modules

其中,modules中包含了baseModules以及platformModules;baseModules中包含了ref及directives的钩子函数,分别为create, update, destory,这些函数会在vnode对应的周期"create", "activate", "update", "remove", "destroy"中被调用。

Patch 流程


patch函数在vue进行update时被调用

文件路径:~/github/vuejs/vue/src/core/vdom/patch.js

条件一:isUndef(oldVnode)

源码注释👹
empty mount (likely as component), create new root element

解读:当未创建vnode时,创建一个新的vnode作为根节点

条件二:!isRealElement && sameVnode

源码注释👹
patch existing root node

解读:如果不是一个真实的dom节点,则对根节点开始进行patchVnode的流程

流程
patchVnode

条件二:isRealElement || sameVnode

解读:不是相同的节点,则创建一个新的dom节点,并把老的节点移除(如果是真实元素的话,会根据这个节点再创建vnode)

流程
create new Elm
➡️
update parent placeholder node element, recursively
➡️
destroy old node

PatchVnode 流程

如果两个vnode引用是相同的,会直接退出

data.hook.prepatch ➡️

directive.cbs.update
data.hook.update ➡️

情况1, vnode.text -> setTextContent
!vnode.text

情况2, oldCh && ch -> updateChildren

情况3, ch -> addVnodes

情况4, oldCh -> removeVnodes

updateChildren 流程

情况1,sameVnode(oldStartVnode, newStartVnode),不需要移动
情况2,sameVnode(oldEndVnode, newEndVnode),不需要移动
情况3,sameVnode(oldStartVnode, newEndVnode),当前节点右移
情况4,sameVnode(oldEndVnode, newStartVnode),当前节点右移
情况5-1,有key的情况 sameVnode(vnodeToMove, newStartVnode),当前节点左移
情况5-2,没有key的情况 创建一个新的节点

当结束上述比对时

如果oldVnode先遍历完,此时newStarIndex到newEndIndex是新增的节点,则addVnodes
如果newVnode先遍历完,此时oldStarIndex到oldEndIndex是需要删除的节点,则removeVnodes

createElm

情况1,如果vnode.elm已经存在,说明该vnode在先前的render中,已经使用,而在这里作为一个新的节点来使用,需要克隆一个新的vnode,不影响之前的节点

如果是组件,则创建对应组件,并退出