πŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
πŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

Conditional Rendering in Vue.js

Learn about Conditional Rendering in this comprehensive Vue.js tutorial. Learn how to use v-if, v-else, and v-show to render HTML elements based on component state.

⚑ Total XP: 0|πŸ’» vuejs XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Select an unlocked node to view details root

πŸš€ LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
πŸŽ“ COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

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

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

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

THE BUG

Putting a v-else on an element that isn't immediately adjacent to its v-if.

THE FIX

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>

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Mutating a Prop Directly

// Wrong const props = defineProps(['count']); function increment() { props.count++; } // Correct const emit = defineEmits(['update:count']); function increment() { emit('update:count', props.count + 1); }

The Solution //

A child component should never assign to a prop it received (e.g. props.title = 'New'). Vue logs "Unexpected mutation of prop" because props are a one-way binding. Copy the prop into local state with ref()/computed() first, or emit an event asking the parent to change its own data.

The Error //

Losing Reactivity by Destructuring reactive()

// Wrong const { name } = reactive({ name: 'Alice' }); // name is now a static string // Correct const state = reactive({ name: 'Alice' }); const { name } = toRefs(state); // name is a live ref

The Solution //

Destructuring a reactive() object copies its properties out as disconnected plain values, so future mutations of the original object won't update the destructured variables. Keep referencing the object's properties directly, or convert it with toRefs() before destructuring.

Continue Learning