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,不影响之前的节点
如果是组件,则创建对应组件,并退出