vue Virtual DOM创建过程

本文详细解析了Vue.js中Virtual DOM的创建过程,从mountComponent的updateComponent开始,经由_render方法,调用createElement函数创建VNode。在createElement内部处理参数并调用_createElement,根据数据类型创建不同类型的VNode。接着,文章探讨了patch过程,包括如何通过patch函数进行DOM更新,并执行diff算法。整个流程展示了Vue.js如何高效地管理和更新DOM结构。
摘要由CSDN通过智能技术生成

vue Virtual DOM创建过程

  1. 在 lifecycle.js 中的mountComponent 中定义了updateComponent,接收_render()方法作为参数,render接收用户传入的render函数
    在render.js中定义了_render方法,其中通过call接收render函数,改变内部this,使用了 c r e a t e E l e m e n t 函 数 , c 与 createElement函数, _c与 createElementccreateElement都是执行createElement函数
  2. 在createElement函数内部最终会返回VNode,但是不是在此处定义,函数主要是处理参数,最后调用_createElement
  3. 在_createElement内部
    先判断 data是否为空,且用_ob_判断是不是响应式数据,是直接用createEmptyVnode返回一个空节点
    判断data是不是有is属性,有记录到tag中 ,is是用来判断是否是组件
    判断 tag 属性
    判断作用域插槽
    核心:判断normalizationType,将数组拍平,转为一维数组
    核心:下方判断是否是字符串,创建vnode对象,或是组件的处理组件的vnode,或是处理自定义标签

VNode的处理过程

  1. 在lifecycle.js 中的mountComponent 中定义了updateComponent,找到_update方法的定义

  2. 利用preVnode判断是不是首次渲染,调用_patch_方法,比较两个vnode差异,把差异更新到真实DOM,返回给el对象

  3. patch是在Vue入口内部的注入的,是在 src/platforms/web/runtime/index.js中,会先判断inBrowser是不是浏览器环境
    patch是一个高阶函数,柯里化的函数,利用createPatchFunction生成,接收nodeOps:一些dom操作,baseModules:处理指令和ref的

  4. patch的实现
    patch接收oldVnode,vnode
    先判断新的Vnode是否存在,
    定义了insertVnodeQueue队列,先插入节点队列,目的是把对应的dom节点挂载到DOM树上,触发对应的insert钩子函数
    判断老的oldVnode是否存在,创建节点,但是不进行挂载
    如果新老节点都存在,利用sameVnode比较选择器和key值,然后进行 更新操作,进行diff算法的patchVnode
    invokeInsertHook函数就是处理节点对应的钩子函数
    返回vnode.elm,新的dom元素返回,记录到elm中

  5. createElm的实现,把vnode转换为真实dom,挂载到dom树上
    先判断vnode是否有elm属性,是判断是不是渲染过
    判断是否组件情况
    存储data,children,tag:标签名称 等属性
    判断是标签节点情况,是否是开发环境,是不是自定义标签,报出警告,之后处理dom元素,处理子元素转换为dom对象,插入到对应的队列中
    判断是注释节点时,创建注释节点,插入到节点队列中
    判断是文本节点时,调用createTextNode创建文本节点,插入到节点队列中

  6. patchVnode对比新旧节点差异,更新到真实dom,就是diff算法的过程
    核心就是触发prepatch函数,执行用户传入的钩子函数
    触发所有模块的update函数,执行用户传入的update函数
    判断有没有文本节点,对比updateChildren函数,判断对应的新老节点的文本内容

  7. updateChildren对比新旧节点,更新dom树,如果节点未变化,重用该节点
    就是snabbdom的updateChildren方法
    先定义新老节点开始,结束的索引,
    先判断是否有重复的key,报出警告
    开始while遍历,当老开始节点小于老结束节点,新开始节点小于新结束节点的索引,开始判断
    先判断老开始节点是否有值,没有的话获取下一个老节点作为索引
    判断老结束节点是否有值,获取前一个节点作为结束节点
    开始对比数组中的四个顶点,新开始,新结束,老开始,老结束,是利用patchVnode比较节点和子节点,进行一一对比
    如果之前索引都不满足,会找到新老想同的key作为对比

    最后做收尾处理,如果老节点未处理完,插入对应的节点到老节点之后
    如果新节点为处理完,移除对应的老节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值