Tutorial Vue 3 – renderizar listas com v-for e :key
verificado a 2 Setembro 2026 · 3 min
O v-for="item in items" repete um elemento para cada entrada de um array. Acrescenta sempre um :key único e estável, tirado dos teus dados e não do índice, para que o Vue acompanhe corretamente cada elemento durante as atualizações.
Uma ficha de produto mostra listas: a composição do tecido, as variantes de cor, as avaliações. A diretiva v-for repete um elemento do template para cada entrada de um array.
Percorrer um array simples
Acrescenta a composição do produto ao estado:
<script setup>
import { ref } from 'vue'
const product = ref('T-Shirt')
const image = ref('/images/t-shirt-bleu.svg')
const inventory = ref(100)
const details = ref(['60 % coton', '30 % laine', '10 % polyester'])
</script>E depois mostra-a:
<ul>
<li v-for="detail in details" :key="detail">{{ detail }}</li>
</ul>O Vue produz um <li> por entrada. Na expressão detail in details, details é o array e detail é o alias do elemento atual, disponível em todo o elemento repetido.
Percorrer objetos
As variantes do produto são objetos, com um identificador e uma cor:
<script setup>
const variants = ref([
{ id: 2234, color: 'Bleu' },
{ id: 2235, color: 'Rouge' }
])
</script>Acede-se às propriedades pela notação com ponto:
<div v-for="variant in variants" :key="variant.id">{{ variant.color }}</div>O índice
Um segundo parâmetro dá a posição no array, a começar em zero:
<li v-for="(detail, index) in details" :key="detail">
{{ index + 1 }}. {{ detail }}
</li>O capítulo 7 vai usar este índice para saber sobre que variante está o rato.
O atributo key
Reparaste no :key em cada ciclo. É o atalho de v-bind:key visto no capítulo 2, e não é decorativo.
Quando a lista muda, o Vue compara a versão antiga com a nova para alterar apenas o necessário. Sem um identificador estável, emparelha os elementos por posição: se inseres uma entrada no início da lista, considera que todos os elementos mudaram de conteúdo e reescreve-os a todos.
Com uma key única e estável, reconhece cada elemento e limita-se a deslocar o que mudou de sítio. Isso evita também um bug clássico: um campo de texto ou uma caixa assinalada que fica agarrada ao elemento errado depois de uma ordenação.
Três regras para a chave:
- Única na lista.
- Estável: a mesma entrada mantém a mesma chave de uma renderização para a outra.
- Nunca o índice, a não ser que a lista nunca mude. O índice muda quando se insere, se elimina ou se ordena: é precisamente aí que não se pode confiar nele.
Usa o identificador dos teus dados. Aqui, o variant.id para as variantes, e a própria string para os detalhes, já que são únicas.
Desde o Vue 3, o v-if é avaliado antes do v-for. A variável do ciclo ainda não existe e o Vue lança um erro do género variant is not defined. Filtra a lista numa propriedade computada, ou passa o ciclo para um <template> interior.
<!-- ne fonctionne pas -->
<div v-for="variant in variants" v-if="variant.enStock">…</div>
<!-- fonctionne -->
<template v-for="variant in variants" :key="variant.id">
<div v-if="variant.enStock">…</div>
</template>Percorrer outra coisa que não um array
O v-for aceita também um objeto, uma string ou um número inteiro:
<!-- objet : valeur, clé, index -->
<li v-for="(valeur, cle) in produit" :key="cle">{{ cle }} : {{ valeur }}</li>
<!-- nombre : de 1 à 5, pas de 0 à 4 -->
<span v-for="n in 5" :key="n">{{ n }}</span>Idêntico no template. Só muda a declaração do array: data() { return { details: [...] } } em vez de const details = ref([...]).
v-for. Depois acrescenta uma terceira variante de cor ao array e confirma que aparece sem mais nenhuma alteração.