当元素没有id时,对于v-for使用什么键?

时间:2019-06-04 18:42:14

标签: vue.js v-for

使用v-for时,包含keystrongly recommended。此外,如here所述,将数组索引用作键实际上并没有帮助。

如果元素具有id属性,那就太好了-您可以将其用作键。但是,当元素具有id属性时该怎么办?在这种情况下,您应该使用什么作为密钥?

1 个答案:

答案 0 :(得分:0)

更好的解决方案

更好的解决方案是使用外部库从对象的值生成哈希码,并将其用作ID。即object-hash

使用object-hash

的示例

const hash = objectHash; // this should be the import i.e. require('object-hash');

new Vue({
  el: '#app',
  template: `
  <div>
    <p v-for="item in itemsWithHash" :key="item.key">
      {{item.name}} {{item.lastname}}<br>key: {{ item.key }}
    </p>
  </div>
  `,
  data: () => ({
    items: [
      { name: 'john', lastname: 'doe' },
      { name: 'bob', lastname: 'smith' },
      { name: 'alice', lastname: 'james' }
    ]
  }),
  computed: {
    itemsWithHash() {
      return this.items.map(i => ({ ...i, key: hash(i) }));
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/object-hash@1.3.1/dist/object_hash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

确定解决方案

您可以将迭代的index用作键,但是请记住,如果按索引更新项目,则不会触发视图的更改。 (Vue使用密钥来检测更改,因此如果密钥未更新,它将不会重新呈现模板)

<div v-for="(item, i) in items" :key="i">
    // some content.
</div>

请注意以下示例,其中直接通过索引对项进行变异不会更新视图,而是将更改打印到控制台:

new Vue({
  el: '#app',
  template: `
  <div>
    <p v-for="(item, index) in items" :key="index">
      {{item.name}} {{item.lastname}}<br>index: {{ index }}
      <button @click="changeForMary(index)"> Replace with Mary Smith</button>
    </p>
  </div>
  `,
  data: () => ({
    items: [
      { name: 'john', lastname: 'doe' },
      { name: 'bob', lastname: 'smith' },
      { name: 'alice', lastname: 'james' }
    ]
  }),
  methods: {
    changeForMary(index){
      this.items[index] = { name: 'mary', lastname: 'smith' };
      console.log(`index ${index} changed to ${JSON.stringify(this.items[index], null, '\t')}`);
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/object-hash@1.3.1/dist/object_hash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>