Conditional Rendering — Two Ways
v-if, v-else & v-show
v-if mounts/unmounts elements while v-show toggles CSS display. Pick the right one based on how often the condition flips.
What you'll learn
- Use v-if / v-else-if / v-else
- Use v-show for frequent toggles
- Know the cost of each
Vue offers two directives for conditional rendering. They look similar but behave very differently under the hood.
v-if, v-else-if, v-else
The v-if family controls whether an element is in the DOM at all. When the condition flips to false, Vue unmounts the element and destroys its component state.
<script setup lang="ts">
import { ref } from 'vue'
const status = ref<'loading' | 'ok' | 'error'>('loading')
</script>
<template>
<p v-if="status === 'loading'">Loading…</p>
<p v-else-if="status === 'error'">Something went wrong</p>
<p v-else>All good</p>
</template> You can group multiple elements under one condition with a template wrapper:
<template v-if="user">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</template> v-show
v-show always renders the element and toggles the CSS display property. The element stays mounted, so its state survives.
<template>
<div v-show="isOpen" class="panel">Panel content</div>
</template> When false, Vue applies an inline style of display: none. There is no mount cost on toggle, but the DOM node is always there.
Choosing Between Them
Use v-if when the condition rarely changes, or when rendering the branch is expensive and you would rather skip it entirely. Use v-show when the user toggles visibility frequently (think dropdowns, tooltips, accordion panels).
One more catch: v-if remounts the element each time it returns, so any local component state (input values, scroll positions, refs) resets. v-show preserves all of it.
v-for — Rendering Lists →