Vue conditional rendering controls which elements appear on the page based on reactive state. Vue offers v-if, v-else-if, v-else, and v-show to handle conditional branches in templates.
Although v-if and v-show look similar visually, they behave very differently in the browser DOM. Knowing when to use each directive keeps your app responsive and avoids unnecessary component re-mounts.
flowchart TD
Check{"Condition Truthy?"}
Check -->|v-if true| Mount["Mount Element to DOM"]
Check -->|v-if false| Unmount["Remove Element from DOM"]
Check -->|v-show toggle| CSS["Toggle CSS display: none"]
v-if and v-show| Directive | DOM Behavior | Toggle Cost | Best Used For |
|---|---|---|---|
v-if |
Adds or removes nodes from DOM | Higher when toggled often | Auth views, error states, rare branches |
v-show |
Always renders; sets display: none |
Very low (CSS only) | Tabs, accordions, frequent toggles |
You can also place v-if on a <template> wrapper to toggle multiple sibling elements at once without adding an extra <div> to the DOM.
<script setup>
import { ref } from 'vue';
const userRole = ref('guest');
const isDrawerOpen = ref(false);
</script>
<template>
<div class="role-switcher">
<div class="buttons">
<button @click="userRole = 'admin'">Admin</button>
<button @click="userRole = 'user'">User</button>
<button @click="userRole = 'guest'">Guest</button>
</div>
<div v-if="userRole === 'admin'" class="panel admin">
<h3>Administrator Dashboard</h3>
<p>Full system permissions granted.</p>
</div>
<div v-else-if="userRole === 'user'" class="panel user">
<h3>User Portal</h3>
<p>Standard account access enabled.</p>
</div>
<div v-else class="panel guest">
<h3>Guest View</h3>
<p>Sign in to access your account details.</p>
</div>
<button @click="isDrawerOpen = !isDrawerOpen">Toggle Help Drawer</button>
<div v-show="isDrawerOpen" class="help-drawer">
<p>Tip: Switch roles above to preview each panel.</p>
</div>
</div>
</template>
v-if and v-for on One Element: In Vue 3, v-if evaluates before v-for, so v-if cannot read the loop variable. Filter the list in a computed() property or wrap the loop in <template v-for>.v-if and v-else: A v-else or v-else-if element must appear right after its matching v-if element. Placing another tag in between breaks the chain.v-show on <template>: v-show relies on CSS display, and <template> renders no DOM node. Always use v-if on <template> wrappers.v-if destroy child component state when hidden?Yes. When a v-if condition turns false, Vue unmounts the child component, runs its cleanup hooks, and resets its local state when mounted again.
v-show over v-if?Use v-show when users toggle a panel, dropdown, or tooltip frequently, because keeping the element mounted avoids rebuilding DOM nodes repeatedly.
v-if affect initial page load performance?v-if is lazy: if the starting condition is false, Vue skips rendering that block until the condition becomes true, which speeds up initial mount.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With