Control the visibility of elements dynamically.
1The v-if Directive
v-if is a directive used to conditionally render a block. The block will only be rendered if the directive's expression returns a truthy value. If it returns false, Vue completely removes the element and its children from the Document Object Model (DOM).
2v-else and v-else-if
You can use v-else to indicate an 'else block' for v-if. A v-else element must immediately follow a v-if or a v-else-if element - otherwise it will not be recognized.
3v-show vs v-if
v-show is another option. The difference is that an element with v-show will always be rendered and remain in the DOM; v-show simply toggles the display CSS property of the element. Use v-show if you need to toggle something very frequently.
4Step-by-Step Breakdown
Often, you want to show or hide elements based on a condition (like showing a "Log out" button only if the user is logged in).
Vue uses the v-if directive for conditional rendering. If the expression inside v-if evaluates to true, the element is rendered.
Which directive is used to conditionally render a block of HTML?
- βv-show
- βv-if
- βv-condition
You can chain conditions using v-else-if and v-else. These must immediately follow a v-if element.
Important: v-if actually completely destroys and re-creates the DOM elements. If the condition is false, the element does not exist in the DOM at all.
When a v-if condition is false, what happens to the element in the DOM?
- βIt gets display: none
- βIt gets opacity: 0
- βIt is completely removed from the DOM
What if you want to toggle an element rapidly? Destroying and recreating DOM elements is expensive. For rapid toggling, use v-show.
v-show ALWAYS renders the element in the DOM, but it uses CSS display: none to hide it. It is much faster for frequent toggling.
Which directive should you use if you need to toggle an element's visibility very frequently, to avoid expensive DOM destruction/creation?
- βv-if
- βv-show
- βv-hide
Summary: Use v-if if the condition rarely changes (e.g., User is Admin). Use v-show for things that toggle constantly (e.g., Accordions, Dropdowns).
Level Up π
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1v-if Fully Removes Inert Content from the Accessibility Tree
Because v-if destroys the element, screen readers correctly skip it entirely with no extra work β the right choice for content that's genuinely not relevant right now, whereas v-show only hides visually via CSS and, without additional aria-hidden handling, can leave stale content technically reachable by assistive tech navigating the raw DOM.
<div v-if="hasError" role="alert">{{ errorMessage }}</div>SEO Implications
- 1
v-if Content Must Be True on First Render to Be Indexed by a Non-JS Crawler
Content behind a v-if that starts false and only becomes true after a client-side interaction or a client-only data fetch does not exist in the DOM at all during the initial render, including during SSR β if that content needs to be indexable, the condition must already evaluate to true using data available at server-render time, not after a subsequent client-only effect.
Best Practices
Use v-show for High-Frequency Toggles, v-if for Rare/Structural Ones
Reserve v-if for conditions that rarely flip (feature flags, role checks, route guards) since it pays a re-render/re-mount cost every time it flips. Use v-show for UI that toggles often within a session β dropdowns, tabs, accordions β since it only pays a cheap CSS display toggle after the first render.
Frequent Bugs
Putting a v-else on an element that isn't immediately adjacent to its v-if.
A v-else (or v-else-if) must be the very next sibling element after the v-if block in the template, with nothing in between; otherwise Vue cannot associate them and either throws a compile warning or treats the v-else as an unrelated, unconditional element.
Real-World Examples
A Three-State Async Loading UI
A data-fetching component chains v-if/v-else-if/v-else across a loading state, an error state, and the loaded data, guaranteeing exactly one of the three UI branches exists in the DOM at any given moment.
<div v-if="status==='loading'">Loadingβ¦</div>
<div v-else-if="status==='error'">{{ error }}</div>
<div v-else>{{ data }}</div>