微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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);
      }
    }
    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、如果旧节点先循环完毕,说明新节点有要插入的节点

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐