虚拟DOM优点

  • 减少操作真实dom,减少浏览器端重绘,提高性能
    • 虚拟DOM可以将多次操作合并为一次操作。
    • 虚拟DOM借助DOM diff 可以将多余的操作省略
  • 跨平台

Key

优点

  • 可以用于强制替换元素或者组件,当需要触发完整的生命周期或者过渡动画的时候可以使用不同的key来实现
  • 如果不使用Key的话,vue在patch node的时候尽可能的减少动态元素并复用相同类型元素。如果使用key之后,vue对象相同类型的元素之火做移动,并移除key不存在的元素。

    情景

    数组[1,2,3] 替换成 [0,2,3]
    在不设置key的情况下,只会更改一个dom操作

  • 第一个老的Vnode和新的vnode是sameNode,则会调用patchNode比较vnode

  • 由于第一个老的Vnode和新的Vnode的text不一样,则直接更新老Vnode的text值
  • 然后继续对比第二个老的Vnode和新的Vnode,是sameVnode并且vnode也是一样的,不做任何改动
  • 然后继续对比第三个老的Vnode和新的Vnode,是sameVnode并且vnode也是一样的,不做任何改动
  • 循环结束,整个过程值更改了一个dom操作

在设置了key的情况下,会有一次插入和移除的dom操作

  • 第一个新的Vnode和第一个老的VNode不是sameVNode
  • 于是比较最后一个老的Vnode和最后一个新的VNode,是sameVNode,节点内容也一样,什么也不做
  • 然后比较倒数第一个的老VNode和新Vnode,也是sameVNode,什么都不做
  • 回到比较第一个节点的过程,新的第一个节点在老的节点中找不到对应的相同节点
  • 这个时候创建一个新的li,插入到老的Li在之前
  • 最后把老的第一个Li节点从界面删除
  • 循环结束,整个过程中会插入新的li 节点和删除老的节点,有两次dom操作

    为什么选择带key

    这种是比较简单的数组变化,看起来设置key了还多了一个操作dom的过程。
    但是这种只是适合渲染无状态的组件,对于大多数场景来说,都是有自己的状态的。
    举个例子:一个新闻列表,可点击列表项来将其标记为“已访问”,可通过tab切换“娱乐新闻”或者“社会新闻”

在不带Key属性情况下,在“娱乐新闻”下选项中第二项然后切换到社会新闻,“社会新闻”里的第二项也会是被选中的状态,因为这里复用了组件,保留了之前的状态。

要解决这个问题,可以为列表项带上新闻的id作为唯一key,那么每次列表渲染时都活完全替换所有组件,使其状态正确。