v-if vs v-show in Vue.js
In Vue, both v-if and v-show are used to conditionally display content on the screen. However, they achieve this through entirely different mechanism structures, resulting in different performance implications and lifecycle behaviors.
1. What the Interviewer Is Testing
Interviewers want to see if you understand the underlying DOM mechanisms:
- DOM Tree Insertion: Which directive adds/removes elements from the actual DOM tree?
- Component Lifecycles: Do lifecycle hooks (
mounted,unmounted) fire when toggling conditional views? - Rendering vs Toggling Cost: Which directive is cheaper to render initially versus toggling frequently?
- Template Support: Can they both be used on
<template>blocks?
2. Core Differences
| Feature | v-if | v-show |
|---|---|---|
| Mechanism | Real conditional rendering. Elements are inserted/destroyed. | CSS-based toggling. Modifies the element's display property. |
| DOM Presence | Removed from the DOM completely when false. | Remains in the DOM; hidden using display: none. |
| Lifecycle Hooks | Destroys and recreates elements/components (triggers full lifecycle). | Only compiles once; hooks do not re-run when toggling. |
| Initial Render Cost | Low (does not compile or render elements if initially false). | High (renders the element regardless of initial truthy state). |
| Toggle Cost | High (expensive DOM inserts and deletions). | Low (only alters style property). |
<template> Support | Yes (can wrap and conditionally hide groups without a wrapper). | No (cannot be applied to a wrapper <template> tag). |
3. Deep Dive: Mechanism & Performance
v-if: Lazy Conditional Rendering
When v-if evaluates to false, Vue does not compile the node or insert it into the DOM. It is replaced by a lightweight HTML comment placeholder <!---->.
When the state changes to true, Vue initiates compilation, mounts the node, and inserts it into the DOM tree. If applied to a child component, this triggers the child's entire lifecycle starting from beforeCreate/created through to mounted.
<!-- If active is false -->
<!---->
<!-- If active is true -->
<div class="modal">Welcome back!</div>v-show: Simple CSS Toggling
When v-show evaluates to false, Vue compiles the element, mounts it, and inserts it into the DOM. It then simply applies inline CSS display: none to hide it. Toggling the condition only triggers a repaint/reflow of the page without invoking any component lifecycle hooks.
<!-- If active is false -->
<div class="modal" style="display: none;">Welcome back!</div>
<!-- If active is true -->
<div class="modal">Welcome back!</div>4. Best Practices & Guidelines
Use v-show when:
- You need to toggle the element's visibility very frequently (e.g., tooltips, drop-down menus, accordion panels).
- You want the component to remain active and preserve its internal state/DOM nodes (e.g., keeping input focus or video playback state).
- You want child component lifecycle hooks to run only once during the initial mount.
Use v-if when:
- The condition is unlikely to change often (e.g., user authorization status, administrative action zones).
- The initial loading speed is critical, and the conditional section starts as
false.v-ifavoids the overhead of compiling and rendering elements that may never be viewed. - You want to guarantee that subcomponents are fully destroyed and reset when hidden.
