Snabbdom之init方法执行逻辑分析
首先,根据传入的modules初始化cbs对象
调用init方法时传入了modules数组
根据modules数组初始化cbs对象
cbs对象存储了各种模块钩子数组
6种模块钩子数组
- create
- update
- remove
- destroy
- pre
- post
其次,声明了8个功能辅助函数
emptyNodeAt
- 参数:(elm: Element)
- 作用:将真实dom元素转换为虚拟dom节点。
- 返回值:虚拟dom节点
createRmCb
- 参数:(childElm: Node, listeners: number)
- 作用:创建删除真实dom节点的回调函数
- 返回值:删除真实dom节点的回调函数
createElm
-
参数:(vnode: VNode, insertedVnodeQueue: VNodeQueue)
-
insertedVnodeQueue
- 语义:已插入的虚拟dom节点队列。
- 来源:patch函数执行时创建。
- 作用:用于缓存已新增的虚拟dom节点。
-
-
作用:创建真实dom元素,并且更新参数vnode的elm属性。
-
返回值:真实dom元素
-
涉及3个用户钩子
-
vnode.data.hook.init
-
最先被调用
-
实参:(vnode)
- 就是createElm的参数
-
用于在创建真实dom元素前,对虚拟dom节点做一些初始化操作。
-
-
vnode.data.hook.create
-
真实dom元素创建完成后,会被调用
-
实参:(emptyNode, vnode)
-
emptyNode
- 空的虚拟dom节点
-
vnode
- 就是createElm的参数
-
-
触发于在创建完真实dom元素后,此时vnode的elm属性就是真实dom元素。
-
-
vnode.data.hook.insert
- 若用户挂载了insert钩子任务,此时会将vnode添加到insertedVnodeQueue中。
-
-
同时会触发模块钩子create钩子任务
-
实参:(emptyNode, vnode)
-
emptyNode
- 空的虚拟dom节点
-
vnode
- 就是createElm的参数
-
-
触发于创建真实dom元素前。
-
addVnodes
-
参数:
-
( parentElm: Node, before: Node | null, vnodes: VNode[], startIdx: number, endIdx: number, insertedVnodeQueue: VNodeQueue )
-
insertedVnodeQueue
- 用于收集已插入的虚拟dom节点
-
-
-
作用:用于将vnodes中指定开始索引startIdx和结束索引endIdx的虚拟dom节点添加到指定的父真实dom节点parentElm下的before真实dom节点之前。
-
返回值:void
invokeDestroyHook
-
参数:(vnode: VNode)
-
作用:用于触发用户挂载的destroy钩子任务
-
返回值:void
-
涉及到1个用户钩子:vnode.data.hook.destroy
- 最先被调用
- 实参:(vnode)
- 若用户挂载了destroy钩子任务,就会被触发。
-
同时会触发模块destroy钩子任务
- 实参:(vnode)
removeVnodes
-
参数
( parentElm: Node, vnodes: VNode[], startIdx: number, endIdx: number )
-
作用:用于删除父元素parentElm(真实dom元素)下指定vnodes中开始索引startIdx到结束索引endIdx的之间的虚拟dom节点s对应的真实dom元素s。
-
返回值:void
-
调用2个功能辅助函数
- 首先调用invokeDestroyHook函数。
- 再调用createRmCb创建rm函数。
-
同时会触发模块remove钩子任务
-
实参:(ch, rm)
-
ch
- 索引到的虚拟dom节点
-
rm
- 调用createRmCb函数返回的用于删除真实dom元素的回调函数。
-
-
-
涉及到1个用户钩子:vnode.data.hook.remove
-
最后被调用
-
实参:(ch, rm)
-
ch
- 索引到的虚拟dom节点
-
rm
- 调用createRmCb函数返回的用于删除真实dom元素的回调函数。
-
-
若用户挂载了remove钩子任务,就会被触发。
-
updateChildren
-
参数
-
( parentElm: Node, oldCh: VNode[], newCh: VNode[], insertedVnodeQueue: VNodeQueue )
-
insertedVnodeQueue
- 用于收集已插入的虚拟dom节点
-
oldCh
- parentElm元素下旧的真实dom节点对应的虚拟dom节点对象数组
-
newCh
- parentElm元素下应该有的真实dom节点对应的虚拟dom节点对象数组。
-
-
-
作用:用于更新父元素parentElm(真实dom元素)下的真实dom元素。
-
返回值:void
patchVnode
-
参数:(oldVnode: VNode, vnode: VNode, insertedVnodeQueue: VNodeQueue)
-
insertedVnodeQueue
- 用于收集已插入的虚拟dom节点
-
-
作用:用于对比新旧虚拟dom节点并将差异更新到真实dom中
-
返回值:void
-
涉及3个用户钩子
-
vnode.data.hook.prepatch
-
首先被调用
-
实参:(oldVnode, vnode)
-
oldVnode
- 旧的虚拟dom节点
-
vnode
- 新的虚拟dom节点
-
-
对比新旧虚拟dom节点差异前触发
-
-
vnode.data.hook.update
-
触发prepatch钩子后,模块钩子update调用之后触发。
-
实参:(oldVnode, vnode)
-
oldVnode
- 旧的虚拟dom节点
-
vnode
- 新的虚拟dom节点
-
-
-
vnode.data.hook.postpatch
-
当新旧虚拟dom节点之前差异更新到真实dom元素之后触发。
-
实参:(oldVnode, vnode)
-
oldVnode
- 旧的虚拟dom节点
-
vnode
- 新的虚拟dom节点
-
-
-
-
模块钩子update会在触发prepatch钩子后触发。
-
调用了3个功能辅助函数
- updateChildren
- addVnodes
- removeVnodes
最后,返回patch函数
参数:(oldVnode: VNode | Element, vnode: VNode)
作用:用于比较新虚拟dom节点跟旧真实dom元素或旧虚拟dom节点之间的差异,并将其更新到真实的dom树中。
返回值:更新所有差异后的vnode对象
触发了2个模块钩子
-
pre
- 无参数
- 更新补丁前触发
-
post
- 无参数
- 更新补丁后触发
涉及1个用户钩子
-
insertedVnodeQueue[i].data.hook.insert
- 参数:(insertedVnodeQueue[i])
- 在更新补丁之后,模块钩子post调用之前触发。