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: