zoukankan      html  css  js  c++  java
  • VUE:为什么不要将key设置为数组下标i

    来自《Vue.js快跑》
    当使用v-for指令遍历一个数组或是对象,并且给定的数组或对象改变时,Vue不会再重复生成所有的元素,而是智能地找到需要更改的元素,并且只更改这些元素。例如,如果有一个作为列表元素输出到页面上的数组,在它的末尾添加一个新元素,那么页面上现有的元素将保持不变,同时在末尾,新的元素会被创建。如果数组中间的一个元素改变了,则页面上只有对应的元素会更新。可是,如果你在数组的中间删除或是添加一个元素,Vue不会知道该元素对应的是页面上哪一个元素,它会更新从删除或是添加元素的位置到列表结尾之间的每一个元素。对于简单的内容,这也许不是一个问题,但对于复杂的内容和组件,你肯定不希望Vue这么做。使用v-for指令时可以设置一个key属性,通过它可以告诉Vue数组中的每个元素应该与页面上哪个元素相关联,从而删除正确的元素。key属性的值默认为元素在循环时的索引。可以通过下面的代码来了解这是如何工作的:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script src="./js/vue.js"></script>
      </head>
    
      <body>
        <div id="app">
          <demo-key v-for="(item, i) in items" @click.native="items.splice(i, 1)" :key='item'>
            {{ item, i }}
          </demo-key>
        </div>
    
          <script>
          const randomColor = () => `hsl(${Math.floor(Math.random() * 360)}, 75%, 85%)`;
          const DemoKey = {
            template: `<p :style="{ backgroundColor: color }"><slot></slot></p>`,
            data: () => ({
              color: randomColor()
            })
          };
    
          new Vue({
            el: '#app',
            components: {
              DemoKey
            },
            data: () => ({
              items: ['one', 'two', 'three', 'four', 'five']
            }),
          });
        </script>
      </body>
    </html>
    

    上面的示例会输出5个颜色随机的、包含数字1到5的段落元素,如下所示:
    epub_25462658_20
    单击其中的一个段落元素,会将对应的元素从items数组中删除。如果单击第二个段落元素——即图中标签为two的元素——希望那个元素会被彻底删除,然后标签为three的元素会变成第二个。实际上并不会这样!最终你得到的是下面这样的结果:
    epub_25462658_21
    这是Vue的差异对比机制引起的:删除了数组中的第二个元素,而原本的位置上将会变成第三个元素,于是Vue更新页面上对应元素的文本来反映变化,对于下个元素、下下个元素都是如此,一直到数组的结尾。最终它会删除最后一个元素。不过,这很可能并不是你想要的,所以为这个示例添加一个key属性,来告诉Vue应该删除哪个元素:

        <template>
          <demo-key
            v-for="(item, i) in items" :key="item"
            @click.native="items.splice(i, 1)">
            {{ item }}
          </demo-key>
        </template>
    

    key属性必须是一个唯一的数字或者字符串,并与数组中的元素相对应。这个例子中,数组的元素自身就是字符串,所以可以把它们用作key。
    我经常看到有人将key设置为数组的下标(例如在前面例子中设置:key="i")。如果不是什么特殊情况,那么你不会想要这么做的!虽然Vue不会再发出警告,但你会遇到与我刚才向你展示的完全相同的问题,一个并非你期望的元素将被删除。
    现在,单击第二个元素将会把two从数组中删除,同时对应的元素也将被删除,结果如下:
    epub_25462658_23
    总之,无论什么情况,只要允许就应该设置一个key。在组件中使用v-for指令时key属性并不是可选的,正如你在前面的示例中看到的,在那个示例中,Vue将会在控制台中显示一个警告。

  • 相关阅读:
    Javascript
    CSS3新增特性HTML标签类型
    HTML5新增的标签
    prototype __proto__ Function
    oninput
    extend
    hasOwnProperty()
    this prototype constructor
    Array类型判断
    指针
  • 原文地址:https://www.cnblogs.com/jeff-ideas/p/14550709.html
Copyright © 2011-2022 走看看