Renderização Condicional com as Diretivas v-if e v-show no Vue.js
Diretiva v-if
A diretiva v-if permite alterar a estrutura do DOM de uma página com base em uma condição. Ela define se um elemento HTML será exibido ou removido, dependendo de uma expressão booleana. Um exemplo prático:
<!DOCTYPE html>
<html>
<head>
<title>Estudando Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p v-if="visible">Primeiro parágrafo</p>
<p>Segundo parágrafo</p>
<button v-on:click="visible = !visible">{{ visible ? 'Ocultar o Primeiro parágrafo' : 'Exibir o Primeiro parágrafo' }}</button>
</div>
<script>
Vue.createApp({
data() {
return { visible: true };
},
}).mount("#app");
</script>
</body>
</html>A condição usada pela v-if retorna um valor true ou false. Quando é true, o elemento associado é renderizado no DOM; quando é false, ele é removido. No exemplo acima, a propriedade visible determina a visibilidade do primeiro parágrafo.
A alternância entre exibir ou ocultar o elemento ocorre ao clicar no botão, que altera o valor de visible.
Exemplo de renderização condicional com elemento renderizado
Exemplo de renderização condicional com elemento oculto
v-else
A diretiva v-else pode complementar a v-if, permitindo que outro elemento seja exibido caso a condição inicial seja avaliada como false.
<!DOCTYPE html>
<html>
<head>
<title>Estudando Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p v-if="visible">Primeiro parágrafo</p>
<p v-else>Segundo parágrafo</p>
<button v-on:click="visible = !visible">{{ visible ? 'Ver o parágrafo 2' : 'Ver o parágrafo 1' }}</button>
</div>
<script>
Vue.createApp({
data() {
return { visible: true };
},
}).mount("#app");
</script>
</body>
</html>Neste caso, quando visible é true, o primeiro parágrafo é exibido; caso contrário, o segundo parágrafo é mostrado. A alternância entre os parágrafos ocorre conforme o estado de visible é atualizado.
Template
Por ser uma diretiva, v-if pode ser aplicada apenas a um único elemento. Para agrupar vários elementos sob a mesma condição, o componente <template> pode ser utilizado como contêiner:
<!DOCTYPE html>
<html>
<head>
<title>Estudando Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<div id="app">
<template v-if="visible">
<h1>Título 1</h1>
<p>Parágrafo 1</p>
</template>
<template v-else>
<h1>Título 2</h1>
<p>Parágrafo 2</p>
</template>
<button v-on:click="visible = !visible">{{ visible ? 'Ver o bloco 2' : 'Ver o bloco 1' }}</button>
</div>
<script>
Vue.createApp({
data() {
return { visible: true };
},
}).mount("#app");
</script>
</body>
</html>
ℹ️ O elemento
<template>não é renderizado no DOM. Ele funciona apenas como um contêiner lógico para os elementos que compartilham a mesma condição.
Se for necessário utilizar um elemento HTML explícito como contêiner, como <div>, ele pode substituir o <template>:
<!DOCTYPE html>
<html>
<head>
<title>Estudando Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div v-if="visible">
<h1>Título 1</h1>
<p>Parágrafo 1</p>
</div>
<div v-else>
<h1>Título 2</h1>
<p>Parágrafo 2</p>
</div>
<button v-on:click="visible = !visible">{{ visible ? 'Ver o bloco 2' : 'Ver o bloco 1' }}</button>
</div>
<script>
Vue.createApp({
data() {
return { visible: true };
},
}).mount("#app");
</script>
</body>
</html>Diretiva v-else-if
A diretiva v-else-if expande as possibilidades do v-if, permitindo a avaliação de condições intermediárias em uma sequência lógica. No exemplo a seguir, diferentes elementos são exibidos com base no número digitado:
<!DOCTYPE html>
<html>
<head>
<title>Estudando Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<div id="app">
<input type="number" v-model="number" />
<p v-if="number == 1">Um</p>
<p v-else-if="number == 2">Dois</p>
<p v-else-if="number > 2 && number < 7">Alguns</p>
<p v-else>Muitos</p>
</div>
<script>
Vue.createApp({
data() {
return { number: 1 };
},
}).mount("#app");
</script>
</body>
</html>
A sequência de condições é avaliada até que a primeira condição verdadeira seja atendida. Caso nenhuma das condições seja satisfeita, o bloco v-else será exibido.
Também é possível utilizar a diretiva v-else-if com template:
<p>
<template v-if="number == 1">Um</template>
<template v-else-if="number == 2">Dois</template>
<template v-else-if="number > 2 && number < 7">Alguns</template>
<template v-else>Muitos</template>
</p>Diretiva v-show
A diretiva v-show também é utilizada para condicionalmente exibir ou ocultar elementos. No entanto, diferentemente de v-if, sua implementação mantém os elementos no DOM e ajusta a visibilidade via CSS. No exemplo abaixo, um bloco div é exibido ou ocultado com base na condição de visibilidade:
<!DOCTYPE html>
<html>
<head>
<title>Estudando Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div v-show="visible">
<h2>Título</h2>
<p>Texto</p>
</div>
<button v-on:click="visible = !visible">{{ visible ? 'Ocultar' : 'Exibir' }}</button>
</div>
<script>
Vue.createApp({
data() {
return { visible: true };
},
}).mount("#app");
</script>
</body>
</html>O bloco div é exibido ou ocultado conforme o valor da propriedade visible. O botão alterna esse valor, mudando a visibilidade do elemento.
Diferenças entre v-if e v-show
A principal diferença entre v-if e v-show está na manipulação do DOM. A diretiva v-if remove e insere os elementos no DOM conforme a condição, enquanto v-show mantém o elemento no DOM e altera sua visibilidade ajustando a propriedade display via CSS (display: none; para ocultar).
A escolha entre as duas diretivas depende do cenário. Para elementos que alternam visibilidade com frequência, v-show é mais eficiente, pois evita alterações na estrutura do DOM. Já v-if é preferível para elementos que devem ser renderizados ou removidos raramente, reduzindo o número de elementos ativos no DOM.
Documentação oficial: