Vue中的key的作用

180 阅读3分钟

key 是为 Vue 中的虚拟 DOM 节点(vNode)标记唯⼀性的 id。

作用: 给虚拟dom添加标识, (优化复用对比策略, 优化渲染性能)

主要考察:

  1. vue 的更新机制 (差异化更新) 对比新旧虚拟dom 进行更新视图

    为什么对比虚拟dom, 而不对比真实的dom ? 真实的dom太复杂, 对比起来性能太差

  2. 虚拟dom: 使用 js 对象的方式, 模拟真实的 dom 结构

    属性的量大大的减少了, 没有真实dom的那么多无效的属性, 对比起来性能高很多

  3. diff 算法: 默认的对比(diff) 机制, 同层兄弟元素, 是按照下标进行对比的, 但是加了 key, 就相当于给虚拟dom加了个标识

    对比策略, 就是对相同key的元素进行对比了, 在列表v-for中, key的使用尤为常见, 可以用于优化渲染性能

diff算法

diff 算法的基本策略 (对比新旧虚拟dom差异的一种算法):

  1. 由于dom结构是一个树形结构, 就算是对比新旧虚拟dom, 一样是在对比树形结构

    而树形结构, 每往下都一层, 遍历成本就越高

  2. 为了避免一些无效的对比, diff算法, (tree diff) 优先比较树的根节点

    如果根节点元素类型(组件), 是一致的, 才考虑复用元素内部的结构

    如果根节点元素类型(组件), 不一致, 直接销毁, 重新构建新的结构

    <div>
        <span>我是内容</span>
    </div>
    ​
    ​
    新
    <li>
        <a href="#">我是内容</a>
        <span>我是内容</span>
    </li>
    

    大大的提升了对比的效率

  3. 同一根节点下, 同级兄弟元素, 默认的对比策略: 按照下标对比

    <div class="box">
        <h1>大标题</h1>
        <p>内容</p>
    </div>
    ​
    新
    <div class="message">
        <h1>测试标题</h1>
        <p>内容</p>
    </div>
    
  4. 同一根节点下, 同级兄弟元素, 如果配置 key 属性, 那么对比的策略, 就不是按照下标, 而是按照key进行 一一对比

    旧
    <div class="box">
        <h1 key="201">大标题</h1>
        <p key="202">内容</p>
    </div>
    ​
    新
    <div class="message">
        <h1 key="200">大标题</h1>   // 新结构
        <p key="202">内容</p>    // 对比出来, 原来结构有key="202", 进行对比, 完成了复用
    </div>
    

    如果你希望一个结构, 并不进行复用, 就是希望某个组件某个结构, 能够重新构建, 可以设置一个不同的 key

key的常见应用场景

key 的常见应用场景 => v-for, v-for 遍历的列表中的项的顺序, 非常的容易改变

1 往后面加, 默认的对比策略, 按照下标, 没有任何问题

// 旧
<ul>
  <li>张三</li>
  <li>李四</li>
</ul>
​
// 新
<ul>
  <li>张三</li>
  <li>李四</li>
  <li>王五</li>
</ul>

2 往前面加, 由于下标变了, 如果按照之前的下标对比, 元素是混乱的, 策略: 加上key

一旦加上了key, 就是按照 key 进行新旧dom的对比了

// 旧 
<ul>
  <li key="17">张三</li>
  <li key="31">李四</li>
</ul>
​
// 新  [ { id: 17, name: '张三' }, ... ]
<ul>
  <li key="52">王五</li>
  <li key="17">张三</li>
  <li key="31">李四</li>
</ul>

总结: key 就是给 虚拟dom 添加了一个 标识, 优化了对比策略!!!

\