Snabbdom之init方法执行逻辑分析

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调用之前触发。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值