v-if, v-else & v-show

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.

4 min read Level 1/5 #vue#directives#conditional
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 →