最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

怎样使用vue中diff算法

来源:懂视网 责编:小采 时间:2020-11-27 19:37:51
文档

怎样使用vue中diff算法

怎样使用vue中diff算法:这次给大家带来怎样使用vue中diff算法,使用vue中diff算法的注意事项有哪些,下面就是实战案例,一起来看一下。虚拟domdiff算法首先要明确一个概念就是diff的对象是虚拟dom,更新真实dom则是diff算法的结果Vnode基类 constructor ( 。
推荐度:
导读怎样使用vue中diff算法:这次给大家带来怎样使用vue中diff算法,使用vue中diff算法的注意事项有哪些,下面就是实战案例,一起来看一下。虚拟domdiff算法首先要明确一个概念就是diff的对象是虚拟dom,更新真实dom则是diff算法的结果Vnode基类 constructor ( 。

  1. 比较二者引用是否一致

  2. 之后asyncFactory不知道是做什么的,所以这个比较看不懂

  3. 静态节点比较key,相同后也不做重新渲染,直接拷贝componentInstance(once命令在此生效)

  4. 如果vnode是文本节点或注释节点,但是vnode.text != oldVnode.text时,只需要更新vnode.elm的文本内容就可以

  5. children的比较

  • 如果只有oldVnode有子节点,那就把这些节点都删除

  • 如果只有vnode有子节点,那就创建这些子节点,这里如果oldVnode是个文本节点就把vnode.elm的文本设置为空字符串

  • 都有则updateChildren,这个之后详述

  • 如果oldVnode和vnode都没有子节点,但是oldVnode是文本节点或注释节点,就把vnode.elm的文本设置为空字符串

  • updateChildren

    这部分重点还是关注整个算法

    首先四个指针,oldStart,oldEnd,newStart,newEnd,两个数组,oldVnode,Vnode。

    function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
     let oldStartIdx = 0
     let newStartIdx = 0
     let oldEndIdx = oldCh.length - 1
     let oldStartVnode = oldCh[0]
     let oldEndVnode = oldCh[oldEndIdx]
     let newEndIdx = newCh.length - 1
     let newStartVnode = newCh[0]
     let newEndVnode = newCh[newEndIdx]
     let oldKeyToIdx, idxInOld, vnodeToMove, refElm
     while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
     if (isUndef(oldStartVnode)) {
     oldStartVnode = oldCh[++oldStartIdx] // Vnode has been moved left
     } else if (isUndef(oldEndVnode)) {
     oldEndVnode = oldCh[--oldEndIdx]
     } else if (sameVnode(oldStartVnode, newStartVnode)) {
     patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue)
     oldStartVnode = oldCh[++oldStartIdx]
     newStartVnode = newCh[++newStartIdx]
     } else if (sameVnode(oldEndVnode, newEndVnode)) {
     patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue)
     oldEndVnode = oldCh[--oldEndIdx]
     newEndVnode = newCh[--newEndIdx]
     } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
     patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue)
     canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))
     oldStartVnode = oldCh[++oldStartIdx]
     newEndVnode = newCh[--newEndIdx]
     } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
     patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue)
     canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)
     oldEndVnode = oldCh[--oldEndIdx]
     newStartVnode = newCh[++newStartIdx]
     } else {
     if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
     idxInOld = isDef(newStartVnode.key)
     ? oldKeyToIdx[newStartVnode.key]
     : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)
     if (isUndef(idxInOld)) { // New element
     createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
     } else {
     vnodeToMove = oldCh[idxInOld]
     if (sameVnode(vnodeToMove, newStartVnode)) {
     patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue)
     oldCh[idxInOld] = undefined
     canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)
     } else {
     // same key but different element. treat as new element
     createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)
     }
     }
     newStartVnode = newCh[++newStartIdx]
     }
     }
     if (oldStartIdx > oldEndIdx) {
     refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm
     addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)
     } else if (newStartIdx > newEndIdx) {
     removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
     }
     }

    一个循环比较的几种情况和处理(以下的++ --均指index的++ --)比较则是比较的node节点,简略写法 不严谨 比较用的是sameVnode函数也不是真的全等

    整体循环不结束的条件oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx

    1. oldStart === newStart,oldStart++ newStart++

    2. oldEnd === newEnd,oldEnd-- newEnd--

    3. oldStart === newEnd, oldStart插到队伍末尾 oldStart++ newEnd--

    4. oldEnd === newStart, oldEnd插到队伍开头 oldEnd-- newStart++

    5. 剩下的所有情况都走这个处理简单的说也就两种处理,处理后newStart++

  • newStart在old中发现一样的那么将这个移动到oldStart前

  • 没有发现一样的那么创建一个放到oldStart之前

  • 循环结束后并没有完成

    还有一段判断才算完

    if (oldStartIdx > oldEndIdx) {
     refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm
     addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)
     } else if (newStartIdx > newEndIdx) {
     removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
     }

    简单的说就是循环结束后,看四个指针中间的内容,old数组中和new数组中,多退少补而已

    相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

    推荐阅读:

    微信小程序开发中怎样实现搜索内容高亮功能

    如何在项目中使用js中存储键值

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    怎样使用vue中diff算法

    怎样使用vue中diff算法:这次给大家带来怎样使用vue中diff算法,使用vue中diff算法的注意事项有哪些,下面就是实战案例,一起来看一下。虚拟domdiff算法首先要明确一个概念就是diff的对象是虚拟dom,更新真实dom则是diff算法的结果Vnode基类 constructor ( 。
    推荐度:
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top