zoukankan      html  css  js  c++  java
  • 为什么应该在 v-for 中使用 :key?

    input 中的 key

    引用 vue 官方文档的原话:

    vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。

    这样容易导致一些问题。因为类似 <input> , <select> , <textarea> 这样的元素都有一个internal state 保存着元素的值,而在元素复用时,这个值是会得到保留的。

    我们来看一个登陆方式切换的例子:

    <div v-if="isUser">
        <label>Login with account</label>
        <input type="text" placeholder="Enter your account">
    </div>
    <div v-else>
        <label>Login with email</label>
        <input type="text" placeholder="Enter your email">
    </div>
    
    <button @click="isUser=!isUser">click to toggle</button>
    

    我们会发现,在点击按钮切换登录方式的时候,输入框中已有的内容 不会被清除 ,这是因为input 的 internal state 保留着元素的值。

    如果我们希望切换的时候不保留这个值呢?我们可以给两个 input 添加不同的 :key 。因为 vue 是将 key 作为唯一标识从而来识别复用的元素的,如果两个元素的 key 不同,那么就相当于告诉 vue“这两个元素是完全独立的,不要复用它们”。

    v-for 中的 key

    同样的,使用 v-for 更新已渲染的元素列表时,默认用 就地复用 策略。列表数据修改的时候,vue 会根据 key 去判断某个值是否修改 —— 如果修改,则重新渲染这一项,否则复用之前的元素。在 v-for 中使用 key 是一个最佳实践,但是我们需要注意使用的是什么 key 。

    假如我们想要在如下数组 [A,B,C,D,E] 的 B 和 C 之间插入 F:

    index   id    Array.elem
    0        1       A
    1        2       B
    2        3       C
    3        4       D
    4        5       E
    

    如果是使用 index 作为 key :

    • 在末尾插入 F 的话没有问题,因为这个时候不影响前面元素的 index,每个元素的 index 不变,而 vue 可以依据这些 index 对元素进行复用;但是现在是在中间插入 F,一旦插入成功,那么 CDE 的 index 都会改变,这时候 CDE 都需要重新渲染一次。而 AB 的 index 是不变的,所以 AB 可以得到复用。

    如果是使用 id 作为 key :

    • 这里就要注意了,这个 id 是唯一的,也是固定不变的(也可以采用元素本身的值作为这个唯一的 id),不管插入还是删除,元素该是哪个 id 还是哪个 id ,这意味着以这样的 id 作为key 时,所有旧元素都可以得到复用。所以这种情况下,我们只需要渲染新插入的 F 元素即可。

    资源搜索网站大全 http://www.szhdn.com

    Virtual DOM 的 Diff 算法

    下面大致从虚拟DOM的Diff算法实现的角度去解释一下。

    vue 和 react的虚拟 DOM 的 Diff 算法大致相同,其核心是基于两个简单的假设:

    • 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。
    • 同一层级的一组节点,他们可以通过唯一的id进行区分。基于以上这两点假设,使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)。

    引用 react’s diff algorithm 中的例子:

    当某一层有很多相同的节点时,也就是列表节点时,Diff 算法的更新过程默认情况下也是遵循以上原则。 比如一下这个情况:

    我们希望可以在 B 和 C 之间加一个 F,Diff 算法默认执行起来是这样的:

    即把 C 更新成 F,D 更新成 C,E 更新成 D,最后再插入 E,这样显然很没有效率。

    所以我们需要使用 key 来给每个节点做一个唯一标识,Diff 算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

    所以 key 的作用主要是为了高效的更新虚拟 DOM。

  • 相关阅读:
    Voice over IP
    [转】:TCP/IP详解学习笔记(5)
    windows phone 7 version: ObservableCollectionEx (1)
    MA0003 移动智能网原理
    TCP 网络书籍
    windows Phone 7如何实现background的情况下不丢失数据
    最近想要学习和了解的东东
    Windows phone 7 开发注意事项
    android Tab标签下得按钮
    新浪微博教程(一)
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/14024963.html
Copyright © 2011-2022 走看看