zoukankan      html  css  js  c++  java
  • vue中diff算法处理新旧节点的流程

    vue中diff算法处理新旧节点的流程


    patch函数的作用

    function patch(oldVnode: VNode | Element, vnode: VNode): VNode {
        let i: number, elm: Node, parent: Node;
        const insertedVnodeQueue: VNodeQueue = [];
        for (i = 0; i < cbs.pre.length; ++i) cbs.pre[i]();
    
        //是虚拟节点还是dom节点,如果是dom节点包装成虚拟节点
        if (!isVnode(oldVnode)) {
          oldVnode = emptyNodeAt(oldVnode);
        }
        // sameVnode函数比较是否是同一个节点
        if (sameVnode(oldVnode, vnode)) {
          patchVnode(oldVnode, vnode, insertedVnodeQueue);
        } else {
          elm = oldVnode.elm!;
          parent = api.parentNode(elm) as Node;
          createElm(vnode, insertedVnodeQueue);
          <!-- 不是同一个节点,暴力拆除 -->
          if (parent !== null) {
            api.insertBefore(parent, vnode.elm!, api.nextSibling(elm));
            removeVnodes(parent, [oldVnode], 0, 0);
          }
        }
        for (i = 0; i < insertedVnodeQueue.length; ++i) {
          insertedVnodeQueue[i].data!.hook!.insert!(insertedVnodeQueue[i]);
        }
        for (i = 0; i < cbs.post.length; ++i) cbs.post[i]();
        return vnode;
      };
    
    patch函数的作用有两点:
    1.是虚拟节点还是dom节点,如果是dom节点包装成虚拟节点
    2.调用sameVnode函数比较是否是同一个节点。在比较他们的子代
      不是同一个节点,暴力拆除,新节点替换旧节点
    

    sameVnode的比较

    通过sameVnode函数去做的处理。
    如果新的虚拟节点和旧的虚拟节点的key值相同,并且他们的选择器(tag标签)相同
    说明是同一个虚拟节点。{这一句话也是sameVnode函数的工作原理}
    
    function sameVnode(vnode1: VNode, vnode2: VNode): boolean {
      <!-- 新旧节点的key值相同 -->
      const isSameKey = vnode1.key === vnode2.key;
      <!-- 选择器(tag标签)相同 -->
      const isSameSel = vnode1.sel === vnode2.sel;
      return isSameSel && isSameKey ;
    }
    

    diff算法处理新旧节点的流程

    1.patch函数被调用:是虚拟节点还是dom节点,如果是dom节点包装成虚拟节点。
    2.调用sameVnode函数比较是否是同一个节点。如果是在比较他们的子代,
      如果不是暴力拆除,新节点替换旧节点
    
    sameVnode的原理:如果新的虚拟节点和旧的虚拟节点的key值相同,并且他们的选择器(tag标签)相同
    说明是同一个虚拟节点。{这一句话也是sameVnode函数的工作原理}
    

    如何知道是虚拟节点还是DOM节点呢

    export default function (oldVnode,newVnode) {
      // 通过sel属性或者tag属性是否为空或者undefined说明是DOM节点
      if (oldVnode.sel=='' || oldVnode.sel==undefined) {
        // 说明第一个参数是DOM节点,
       //  通过vnode 将DOM节点包装成虚拟dom节点 
      }
    }
    再更新节点的时候是:先插入然后再删除
    

    完整图

    对diff算法的命中查找的解释

    1、新前与旧前
    命中结果:新前与旧前下标同时下移
    2、新后与旧后
    命中结果:新前与旧前下标同时上移
    3、新后与旧前
    命中结果:移动新前指向的这个节点到老节点的旧后之后 。
    4、新前与旧后
    命中结果:移动新前指向的这个节点到老节点的旧前前面。
    注意的点:
    1、命中一种就不在往下判断了,如果都命中不了,就创建一个map映射,移动到旧节点最开始的时候
    2、如果旧节点先循环完毕,说明新节点有要插入的节点
    
    作者:明月人倚楼
    出处:https://www.cnblogs.com/IwishIcould/

    想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,或者关注博主,在此感谢!

    万水千山总是情,打赏5毛买辣条行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主(っ•̀ω•́)っ✎⁾⁾!

    想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

    支付宝
    微信
    本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
    如果文中有什么错误,欢迎指出。以免更多的人被误导。
  • 相关阅读:
    Elasticsearch 在部署时,对 Linux 的设置有哪些优化方 法?
    详细描述一下 Elasticsearch 搜索的过程?
    Memcached 服务特点及工作原理是什么?
    Memcached 服务分布式集群如何实现?
    如何监控 Elasticsearch 集群状态?
    对于 GC 方面,在使用 Elasticsearch 时要注意什么?
    memcached 和 MySQL 的 query ?
    memcached 如何实现冗余机制?
    memcached 能接受的 key 的最大长度是多少?
    memcached 的多线程是什么?如何使用它们?
  • 原文地址:https://www.cnblogs.com/IwishIcould/p/15690583.html
Copyright © 2011-2022 走看看