Fix "elements in interation expect to have 'v-bind:key'" in Vue

May 11, 2022

To fix the "elements in iteration expect to have 'v-bind:key' error" in Vue, you need to set a unique v-bind:key, or :key for short, on the v-for element. The :key should be a JavaScript primitive, like a string or a number.

<div v-for="item in items" v-bind:key="item.id">
  <li>{{item}}</li>
</div>

We recommend using a unique identifier, like a Mongoose ObjectId or uuid, as the :key if you are iterating over an array of objects.

Using the Array Index as the Key

You can also use the array index as the key if you do not have a good unique identifier.

<div v-for="(item, index) in items" v-bind:key="index">
  <li>{{item}}</li>
</div>

However, if you use the array index as the key, be careful if you use a component that relies on internal state in v-for. For example, below the second list is incorrect. The internalValue doesn't line up with value after you click addValueToMiddle because Vue won't re-render existing item components when the items array changes.

Vue.component('item', {
  props: ['value'],
  data() {
    return {
      internalValue: this.value
    };
  },
  template: `<li>Internal: {{internalValue}} Prop: {{value}}</li>`
});

const app = new Vue({
  data: () => ({ items: [1, 2, 3, 4, 5] }),
  template: `
    <div>
      <button @click="addValueToMiddle">Add value to middle</button>
      <ul>
        <item v-for="(i, index) in items" :value="i" :key="index"></item>
      </ul>
    </div>
  `,
  methods: {
    addValueToMiddle() {
      this.items.splice(Math.ceil(this.items.length / 2), 0, this.items.length + 1)
    }
  }
});

Vue School has some of our favorite Vue video courses. Their Vue.js Master Class walks you through building a real world application, and does a great job of teaching you how to integrate Vue with Firebase. Check it out!


Did you find this tutorial useful? Say thanks by starring our repo on GitHub!

More Vue Tutorials