v-for — Rendering Lists

Always Provide a :key

v-for — Rendering Lists

v-for iterates arrays, objects, or numeric ranges. The :key prop makes Vue's diffing fast and predictable.

4 min read Level 2/5 #vue#directives#lists
What you'll learn
  • Iterate an array with v-for
  • Iterate object keys
  • Always set :key

v-for renders one node per item in a list. Pair it with a stable :key and Vue can patch the DOM in place instead of recreating it.

Arrays

<script setup lang="ts">
import { ref } from 'vue'
const items = ref([
  { id: 1, name: 'Pen' },
  { id: 2, name: 'Notebook' },
])
</script>

<template>
  <ul>
    <li v-for="item in items" :key="item.id">{{ item.name }}</li>
  </ul>
</template>

You can also receive the index as a second argument:

<li v-for="(item, i) in items" :key="item.id">
  {{ i + 1 }}. {{ item.name }}
</li>

Objects and Ranges

Objects yield value, key, and index:

<li v-for="(value, key, i) in profile" :key="key">
  {{ i }}. {{ key }}: {{ value }}
</li>

A number iterates from 1 to N inclusive:

<span v-for="n in 5" :key="n">{{ n }}</span>

Keys Matter

Always use a stable, unique key per item. Using the array index as a key looks fine until you insert, remove, or reorder rows: form input values bleed between rows, animations glitch, and child component state attaches to the wrong item.

// good: id is stable
:key="item.id"

// bad: index changes when the list reorders
:key="i"

Skip v-for + v-if on the same element. Instead, filter with a computed and iterate the result.

v-model — Two-Way Binding →