• vue diff 算法学习


    之前跟着视频教程写过一遍虚拟dom的生成和diff 算法, vue 的虚拟dom 来自于 snabbdom 这个库, github代码仓库, 现在重新回顾一遍

    diff 算法是干啥的

    首先要知道 diff 算法到底是用来干什么的? diff 算法不是在两个集合里寻找不同的元素的, 而是找到符合你判断逻辑的相同虚拟节点。比如:vue里面的 sameNode,下面有代码 ;找到相同虚拟节点之后,执行 patch 逻辑, 这里的patch 是 vue 里面的dom操作 , 这里的sameNode匹配只是判断最外层vnode是否相同, 内部还需要 patch 函数进行操作

    diff 算法执行的逻辑

    匹配逻辑, 这里的匹配逻辑使用了多个指针一起走, 每一次循环都会执行一次下面的逻辑, 一次循环走过以后, 对应的下标也会改变, 这里注意下标的改变跟命中逻辑有关
    在这里插入图片描述

    //  diff 算法是用来寻找相同元素进行patch的
          // 下面的方法没有处理边界,
          // 比如你的新标签要比旧的多, 那就需要 diff算法结束后进行一次处理, 把剩余的新标签元素插入到dom中去,
          // 你的新标签如果比旧的少, 那就可能需要你删掉相应的标签
    
          const sameNode = (newNode, node) => {
            return node.key == newNode.key && node.tag === newNode.tag
          }
          const map = new Map()
    
          const arr = [
            { key: 1, tag: 'div' },
            { key: 2, tag: 'div' },
            { key: 5, tag: 'div' },
            { key: 4, tag: 'div' }
          ]
    
          const arr2 = [
            { key: 1, tag: 'div' },
            { key: 2, tag: 'div' },
            { key: 5, tag: 'div' },
            { key: 6, tag: 'div' }
          ]
    
          let startIndex = 0
          let endIndex = arr.length - 1
          let nStartIndex = 0
          let nEndIndex = arr2.length - 1
    
          //命中才能改变当前下标,
          while (startIndex <= endIndex && nStartIndex <= nEndIndex) {
            const item = arr[startIndex]
            const endItem = arr[endIndex]
            const nItem = arr2[nStartIndex]
            const nEndItem = arr2[nEndIndex]
    
            // 新前和旧前的值相等
            if (sameNode(nItem, item)) {
              startIndex++
              nStartIndex++
              console.log('命中了=>现在是新前===旧前', nItem, item)
            } else if (sameNode(nEndItem, endItem)) {
              nEndIndex--
              endIndex--
              console.log('命中了=>现在是新后===旧后', nEndItem, endItem)
            } else if (sameNode(nEndItem, item)) {
              startIndex++
              nEndIndex--
              console.log('命中了=>现在是新后===旧前', nEndItem, item)
            } else if (sameNode(nItem, endItem)) {
              endIndex--
              nStartIndex++
              console.log('命中了=>现在是新前===旧后', nItem, endItem)
            } else {
              console.log('sdfsdfsdfsdf')
              if (map.length === 0) {
                arr.forEach((item, index) => {
                  map.set(item.key, index)
                })
              }
    
              // 匹配有没有命中的元素
              const index = map.get(arr2[nStartIndex].key)
    
              if (index) {
                console.log('最后一个循环找到了,执行patch')
              } else {
                console.log(
                  '直接把旧标签用新的替换掉',
                  `${arr2[nStartIndex].key}${arr2[nStartIndex].tag}`
                )
              }
    
              nStartIndex++
            }
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    解释:

    1. sameNode

    const sameNode = (vnode, newVnode)=>{
    return vnode.key == newVnode.key && vnode.tag === newVnode.tag
    }
    
    • 1
    • 2
    • 3

    推荐去这视频看一遍教程, 就能好好理解虚拟dom和diff算法了

  • 相关阅读:
    【ARM Coresight OpenOCD 系列 3 -- OpenOCD 常用命令与扫描链scan_chain】
    yolo训练时遇到GBK编码问题
    facebook审核流程
    Docker部署FastDFS分布式存储
    Vuex有几种属性以及它们的意义
    《程序员面试金典(第6版)》面试题 02.05. 链表求和(构建一个新链表)
    【DaVinci Developer专题】-44-Software Component软件组件的Multiple Instantiation多次实例化
    【MySQL】MVCC原理分析 + 源码解读 -- 必须说透
    机器学习技术(六)——有监督学习算法之线性回归算法实操
    【数学】【位运算】Divan and bitwise operations—CF1614C
  • 原文地址:https://blog.csdn.net/weixin_43191327/article/details/125023256