Vue.js: Renderização Condicional e Listas

Última atualização: 2026-10-20

A renderização condicional (v-if / v-show) e a renderização de lista (v-for) são as duas diretivas mais utilizadas nos modelos do Vue. A primeira controla se um elemento é exibido ou não, enquanto a segunda controla quantos elementos são exibidos. Juntas, elas são capazes de lidar com 90% dos cenários de interface do usuário.

Compreender as cinco principais diferenças entre v-if e v-for, bem como o uso correto de :key, é essencial para a criação de aplicativos Vue de alto desempenho.

Diretivas relacionados:v-else-if v-show v-for v-if

1. O que você vai aprender

Renderização condicional


2. Um pesadelo de programação: “Instruções if aninhadas” em um painel

(1) Problema: 5 tags v-if aninhadas — um pesadelo para a depuração

O código do painel da Alice ficou fora de controle:

A revisão de código feita por Charlie:

“Alice, isso está impossível de ler. São cinco níveis de aninhamento de v-if. E se adicionarmos mais duas condições? Precisamos de um padrão mais claro.”

(2) Solução com Vue: Simplificação com v-if + Propriedades calculadas

(3) Receita


3. Renderização condicional com v-if / v-else-if / v-else

(1) Sintaxe básica

(2) O elemento template

(3) 5 principais casos de uso

Cenário Usando v-if
Conectado/Não conectado ✅
Carregando.../Carregado ✅
Sem dados/Dados disponíveis ✅
Status do erro ✅
Alternar frequentemente entre mostrar e ocultar ❌ (Use v-show)

▶ Exemplo: 5 maneiras de usar v-if/v-show

▶ Experimente

Saída:

TEXT
show = true → os dois <p> visíveis
show = false → v-if sai do DOM; v-show fica com display: none
type = 'B' → exibe "B"; isAdmin = true → <h1>Admin</h1> + botão

4. 5 principais diferenças entre v-show e v-if

(1) Principais diferenças

(2) 5 comparações importantes

Aspecto v-if v-show
Manipulação do DOM Remove o elemento quando a condição é falsa Permanece sempre no DOM; apenas a propriedade display é alterada
Desempenho da troca Ruim (destruir e reconstruir a cada vez) Bom (apenas CSS)
Renderização inicial Não renderizar se a condição for falsa Sempre renderizar (mesmo que seja invisível)
Compatibilidade com transições ✅ Perfeita (animações de entrada/saída) ❌ Não compatível
Casos de uso Troca ocasional Troca frequente

(3) Recomendações de seleção

JS
// Switch Occasionally(If you are logged in/Not logged in)→ v-if
<div v-if="isLoggedIn">Welcome, {{ user.name }}</div>
<div v-else>Please login</div>

// Frequent switching (e.g. tab switch) → v-show
<button v-show="isActive">Active</button>
<button v-show="!isActive">Inactive</button>

5. Exibição de listas com v-for

(1) Iterando por um array

(2) Iteração sobre objetos

(3) Iterando por números

(4) Iteração por uma string


▶ Exemplo: 5 maneiras de usar v-for

▶ Experimente

Saída:

TEXT
items = 2 → "1. iPhone", "2. MacBook"
user = { name: 'Alice' } → "name: Alice"
n in 5 → 1 2 3 4 5; em 'Hello' → H e l l o

▶ Exemplo: Prioridade entre v-if e v-for

VUE
<!-- In Vue 3, v-if has higher priority than v-for (Vue 2 is the opposite) -->
<ul>
 <!-- Vue 3: First determine v-if, then v-for -->
 <li v-for="user in users" v-if="user.isActive" :key="user.id">
 {{ user.name }}
 </li>
 <!-- ✅ But Vue officially recommends using template to separate -->
 
 <!-- ❌ Incorrect wording(Not recommended) -->
 <li v-for="user in users" v-if="shouldShowUsers(user)" :key="user.id">
 {{ user.name }}
 </li>
 
 <!-- ✅ Recommendations:computed Filter -->
 <li v-for="user in activeUsers" :key="user.id">
 {{ user.name }}
 </li>
</template>
▶ Experimente

Saída:

TEXT
Vue 3: v-if é avaliado antes do v-for
user não existe nesse escopo → erro ao ler user.isActive
Correção: <li v-for="user in activeUsers"> com computed

6. A finalidade de :key e as melhores práticas

(1) O que é :key?

:key Atribua um identificador exclusivo a cada item do v-for para ajudar o Vue a atualizar o DOM de forma eficiente.

(2) Por que o :key é necessário?

100%
graph LR
 A[Original List A B C] --> B[New List B C D]
 B --> C[None key:Possible misalignment]
 B --> D[Has key: Update Correctly]
 
 style C fill:#ff6b6b
 style D fill:#42b883

Quando não há :key:

Quando :key estiver presente:

(3) Melhores práticas para :key

VUE
<!-- ✅ Recommendations:The Only One ID -->
<li v-for="user in users" :key="user.id">

<!-- ✅ Second choice:Unique Field(Email、Mobile phone number, etc.)-->
<li v-for="user in users" :key="user.email">

<!-- ❌ Avoid:index(When the data changes, the alignment is off.)-->
<li v-for="(user, index) in users" :key="index">

<!-- ❌ Never, under any circumstances:random()(Every render is different,Forced Rebuild)-->
<li v-for="user in users" :key="Math.random()">

▶ Exemplo: Comparação de 5 maneiras de usar :key

▶ Experimente

Saída:

TEXT
:key="user.id" → lista estável ao reordenar
:key="i" → conteúdo desalinha após ordenar
:key="Math.random()" → lista recriada a cada render

7. Filtragem / Ordenação / Paginação de listas

(1) Filtragem + Classificação (Propriedades calculadas)

JS
import { ref, computed } from 'vue'

const items = ref([
 { id: 1, name: 'iPhone', price: 999, category: 'phone' },
 { id: 2, name: 'MacBook', price: 2499, category: 'laptop' },
 { id: 3, name: 'iPad', price: 599, category: 'tablet' }
])

const searchQuery = ref('')
const selectedCategory = ref('all')
const sortBy = ref('price') // 'price' / 'name'

// Filter + Sort(computed Automatic Caching)
const filteredItems = computed(() => {
 let result = items.value
 
 // 1. Filter by search term
 if (searchQuery.value) {
 result = result.filter(item =>
 item.name.toLowerCase().includes(searchQuery.value.toLowerCase())
 )
 }
 
 // 2. Filter by Category
 if (selectedCategory.value !== 'all') {
 result = result.filter(item => item.category === selectedCategory.value)
 }
 
 // 3. Sort
 result = [...result].sort((a, b) => {
 if (sortBy.value === 'price') return a.price - b.price
 if (sortBy.value === 'name') return a.name.localeCompare(b.name)
 return 0
 })
 
 return result
})

(2) Paginação

JS
const currentPage = ref(1)
const pageSize = ref(10)

// Data after pagination
const paginatedItems = computed(() => {
 const start = (currentPage.value - 1) * pageSize.value
 return filteredItems.value.slice(start, start + pageSize.value)
})

// Total Number of Pages
const totalPages = computed(() =>
 Math.ceil(filteredItems.value.length / pageSize.value)
)

8. Exercício abrangente: lista com filtro, ordenação e paginação

▶ Exemplo: Exemplo completo de filtragem + ordenação + paginação de listas

▶ Experimente

Saída:

TEXT
Inicial: iPad - $599, iPhone - $999, MacBook - $2499 (por preço)
Buscar "iPho" → apenas iPhone - $999
Categoria "laptop" → apenas MacBook; 1 / 1, Next desabilitado

(1) 📊 5. 5 erros comuns

Erro Sintoma Solução
Nenhuma :key Desalinhamento da lista, baixo desempenho Adicionar :key="item.id"
Como usar v-for e v-if juntos Confusão sobre a prioridade do v-if Envolvendo com template ou usando computed
Use “índice” como chave Desalinhamento durante a classificação Use um ID exclusivo
O v-show não é compatível com <transition> Não é possível criar animações Use v-if em vez disso + <transition>
A lista é muito grande (mais de 100.000) A página trava Use o vue-virtual-scroller para rolagem virtual

Diretivas relacionados:v-else-if v-show v-for v-if

❓ Perguntas Frequentes

P Como faço para escolher entre v-if e v-show?
R Use v-if para alternâncias ocasionais (para economizar na renderização inicial) e v-show para alternâncias frequentes (para evitar destruir e reconstruir o DOM repetidamente). Use v-if para estados de login/logout e v-show para alternância entre abas.
P O :key é obrigatório quando se usa o v-for?
R Recomendamos enfaticamente o uso do :key para evitar problemas de desempenho e incompatibilidades no estado dos componentes. O ideal é usar um ID exclusivo (item.id), seguido pelo index; nunca use o random().
P Qual é a prioridade ao usar v-if e v-for juntos?
R No Vue 3, o v-if tem precedência sobre o v-for (ao contrário do Vue 2). No entanto, a recomendação oficial é evitar usá-los juntos; em vez disso, separe-os usando o template ou filtre usando o computed.
P Qual é a finalidade do elemento template?
R O template é um elemento wrapper lógico do Vue que não é renderizado no DOM. Ele é usado para evitar elementos div desnecessários quando v-if ou v-for incluem vários elementos.
P O que posso fazer se o desempenho da lista for ruim?
R Três otimizações: (1) Adicione :key; (2) Use computed para armazenar em cache os resultados da filtragem/classificação; (3) Para listas grandes (mais de 100.000), use vue-virtual-scroller para rolagem virtual, a fim de renderizar apenas a área visível.
P É possível acessar chaves e valores ao iterar sobre um objeto com v-for?
R Sim. v-for="(value, key, index) in obj", ordem dos parâmetros: valor, chave, índice.
P Como faço para exibir uma mensagem de aviso quando não há dados?
R Use uma combinação de v-if e v-else: <div v-if="items.length">Column </div><div v-else> Data</div>.
P Como faço para destacar um item selecionado em uma lista?
R Adicione um activeIndex a cada item: @click="activeIndex = item.id" :class="{ active: activeIndex === item.id }".

📖 Resumo


📝 Exercícios

  1. Questões básicas (Dificuldade: ⭐)

    Use v-if/v-else para alternar entre os estados de conectado e desconectado:

    • Conectado: exibe o nome de usuário e o botão “Sair”
    • Não conectado: exibe a mensagem “Faça login” e o formulário de login
    • Use um template para agrupar vários elementos
  2. Problemas avançados (Dificuldade: ⭐⭐)

    Como criar uma lista de tarefas usando v-for:

    • 3 status: Todos / Em andamento / Concluídos (alterne entre eles usando os 3 botões)
    • A lista exibe as tarefas com o status correspondente
    • Cada item possui os botões “Concluir” e “Excluir”
    • A mensagem “Inacabado: N itens” é exibida na parte inferior
  3. Problema de desafio (Dificuldade: ⭐⭐⭐)

    Implementar um sistema completo de filtragem, ordenação e paginação de produtos (5 arquivos):

    1. Dados do produto: 30 registros, incluindo nome, preço, categoria e data de criação
    2. Pesquisa: Faça uma pesquisa aproximada por nome
    3. Filtrar por categoria: 5 categorias (todas/celular/laptop/tablet/fones de ouvido)
    4. Ordenar por: Preço (crescente/decrescente), Nome, Mais recentes
    5. Paginação: 10 itens por página, com navegação numérica entre as páginas
    6. Desempenho: armazena em cache os resultados calculados, filtrados e classificados
    7. Otimização de listas extensas: 1.000 itens de teste para garantir um desempenho sem interrupções
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%