• virtual dom


    VDom就是用JS虚拟创建的一个DOM对象,但并没有挂载到页面上,那他的作用是什么? 很简单,那就是个真实DOM做对比,对比两课DOM树的差别来进行局部更新,这样就不用重新渲染整个虚拟DOM树来进行更新,也符合了“数据驱动”的思想,避免了重绘和重排,提高了Web性能。

    1.vue 的虚拟DOM 节点树构建过程

    Vue 先将模板编译成render函数,渲染出虚拟 DOM ,然后再通过virtual DOM的diff方法来更新真实的DOM树。

    这个过程中,还可以通过watcher监听“虚拟DOM”发生的变化并保持追踪;它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,及其子节点,通过这个过程,Vue 会自动保持页面的更新,开发者就可以高效的更新所有DOM节点。

    2.Diff方法:仅在同级的vnode间做diff,递归地进行同级vnode的diff,最终实现整个DOM树的更新

    实例来看下整个diff的过程(节点属性中不带key的情况):

    首先从第一个节点开始比较,不管是oldCh还是newCh的起始或者终止节点都不存在sameVnode,同时节点属性中是不带key标记的,因此第一轮的diff完后,newChstartVnode被添加到oldStartVnode的前面,同时newStartIndex前移一位;

    第二轮的diff中,满足sameVnode(oldStartVnode, newStartVnode),因此对这2个vnode进行diff,最后将patch打到oldStartVnode上,同时oldStartVnodenewStartIndex都向前移动一位

    第三轮的diff中,满足sameVnode(oldEndVnode, newStartVnode),那么首先对oldEndVnodenewStartVnode进行diff,并对oldEndVnode进行patch,并完成oldEndVnode移位的操作,最后newStartIndex前移一位,oldStartVnode后移一位;

    第五轮的diff中,同过程1;

    遍历的过程结束后,newStartIdx > newEndIdx,说明此时oldCh存在多余的节点,那么最后就需要将这些多余的节点删除。

    patch原理:

    function patchElement(parent, newVNode, oldVNode, index = 0) {
    if(!oldVNode) {
      parent.appendChild(newVNode.render())
    } else if(!newVNode) {
      parent.removeChild(parent.childNodes[index])
    } else if(newVNode.tag !== oldVNode.tag || newVNode.text !== oldVNode.text) {
      parent.replaceChild(newVNode.render(), parent.childNodes[index])
    }  else {
    for(let i = 0; i < newVNode.children.length || i < oldVNode.children.length; i++) {
      patchElement(parent.childNodes[index], newVNode.children[i], oldVNode.children[i], i)
      }
    }
    }//对比DOM树变更
  • 相关阅读:
    题目:心灵的抚慰
    间谍网络
    tarjan算法模版
    rect
    学校食堂
    题目:自然的雪糕
    Winform里众多上下文菜单的控制要怎么做?
    ubuntu更新列表
    瞧,Silverlight是如何被部署到客户机的
    盖茨十条成功箴言 值得一生铭记
  • 原文地址:https://www.cnblogs.com/ceceliahappycoding/p/10578045.html
Copyright © 2020-2023  润新知