vue(7)虚拟DOM和diff算法

虚拟DOM

  • 虚拟DOM(vnode)简单点来说就是用JS对象来模拟DOM结构

  • 表达方式:将每一个标签都转为一个对象,这个对象有三个属性:tag props children

  • tag: 标签 也可以是组件

  • props: 标签上的属性和方法

  • children: 标签上的内容或者子节点

  • 使用虚拟DOM的优点:

  • 原生DOM是有非常多的属性和事件的,即使是一个空的div也会占用比较大的内存

  • 使用虚拟dom的话,在dom发生变化的时候,通过diff算法和数据改变前的dom对比,计算出需要改变的dom,然后只对变化的dom进行操作就好,而不是更新整个视图

diff算法

  • 这个原理的过程如下:

  • 1) diff同层比较: 首先需要说明的是,新旧虚拟DOM对比的时候,diff算法只会在同层比较,不会跨级比较。这是一个深度优先的算法,同时是在同层比较的

  • 2)patch算法:当响应式数据发生变化的时候,就会触发setter,然后通过依赖上的dep去通知watcher,这时候watcher就会调用patch算法,给真实DOM打补丁

  • patch算法会比较新的vnode和旧的vnode是否是同一类型的节点,即isSameVnode,它的核心思路如下:

  • 即比较key值,标签名,标签上的data等是否一致

  • 如果不一致,就直接将旧的vnode替换为新的vnode

  • 如果一致就进行更深层次的比较

  • 3)patchVnode算法:当两个节点的类型是一致的话,再进行patchVnode算法的比较

  • 首先判断新的vnode和旧的vnode是否指向同一个对象,如果是,就直接return

  • 如果它们都是文本节点,且不相等,就将真实DOM的文本节点设置为新的vnode的文本节点

  • 如果旧的vnode有子节点,而新的vnode没有子节点,就删除真实DOM的子节点

  • 如果旧的vnode没有直接点,而新的vnode有子节点,就将新的vnode真实化后挂载到真实DOM上

  • 如果两者都有子节点,则执行updateChildren算法来比较子节点

  • 4)updateChildren算法:

  • 该算法用到首尾指针,新的子节点集合和旧的子节点集合,各自有首尾两个指针

  • 新的vnode的首尾,和旧的vnode的首尾两两之间进行比较isSameVnode,看是否是同一类型的节点,即共有四种比较,如果有相等的,就把真实DOM上的对象节点移动到新的vnode的所对应的位置上

  • 如果这四种比较都是不相等的,那么再用新的vnode中的key值去寻找在旧的vnode中可以复用的节点

为何不用index作为key值

  • 比如说,在列表首部新增了一个元素,
  • 这时候新的vnode的头部的元素的key值为0,同时旧的vnode的头部的元素的key值也是0,key值是相等的,但是这两个元素实际上是不相等的
  • 但是在updateChildren算法中,通过isSameVnode算法,是会将这两个元素判定为相同类型的元素的。。这样就会引发很多不必要的错误。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值