Explain what happens to a component instance when a v-if condition toggles: when it is created (mounted), when it is destroyed (unmounted), what lifecycle hooks run, and why local state resets. Contrast with v-show and mention when you should prefer one over the other.
How does v-if affect component creation and destruction?
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
Core ideav-if controls whether a template branch exists. For plain elements it means “insert/remove DOM”. For components it means “mount/unmount the component instance” — so the instance is created when the condition becomes true and destroyed when it becomes false.
When condition... | What Vue does | What you observe |
|---|---|---|
becomes true (first time) | Creates component instance and mounts it | setup()/data() runs, DOM is created, mounted hooks fire |
becomes false | Unmounts component instance and removes DOM | unmounted hooks fire, watchers/listeners cleaned up, DOM disappears |
becomes true again | Creates a new component instance (fresh) | Local state resets (unless state lives outside the component) |
<!-- Parent.vue -->
<script setup>
import { ref } from 'vue';
import Child from './Child.vue';
const show = ref(true);
</script>
<template>
<button @click="show = !show">Toggle</button>
<Child v-if="show" />
</template>
<!-- Child.vue -->
<script setup>
import { onMounted, onBeforeUnmount, ref } from 'vue';
const clicks = ref(0);
let id;
onMounted(() => {
console.log('mounted');
id = window.setInterval(() => console.log('tick'), 1000);
});
onBeforeUnmount(() => {
console.log('beforeUnmount (cleanup)');
window.clearInterval(id);
});
</script>
<template>
<button @click="clicks++">Clicks (resets after v-if): {{ clicks }}</button>
</template>
Area | What happens on v-if=false (unmount) | Why it matters |
|---|---|---|
Local component state | Discarded (next mount starts from initial state) | You lose UI state like input values, counters, local caches |
Watchers / effects | Stopped automatically | Avoids leaks, but also means side effects restart on next mount |
DOM + focus | Removed from DOM | Focus is lost; selection/caret state is gone |
Lifecycle hooks | Vue 3: beforeUnmount/unmounted (Vue 2: beforeDestroy/destroyed) | Interviewers often check that you know it’s actual destruction |
v-if vs v-show (performance + behavior)v-if has higher toggle cost (create/destroy) but zero cost when false (nothing exists). v-show has higher initial cost (always renders once) but cheap toggles (CSS display only).
Use case | Prefer | Reason |
|---|---|---|
Toggles frequently (tabs, dropdown open/close) | v-show | Avoid repeated mount/unmount work; keeps state + DOM |
Toggles rarely (auth gate, expensive panel, route-like branches) | v-if | Don’t pay initial render cost until needed; removes heavy DOM when off |
Must preserve state across toggles but still avoid rendering when hidden | Move state out / keep-alive (when applicable) | State lives outside the destroyed instance, or instance is cached |
<!-- v-show: component stays mounted, just hidden -->
<template>
<Child v-show="show" />
</template>
Forcing recreation even when staying on-screen
If you want to deliberately reset a component, you can change its key. A key change forces Vue to treat it as a different instance (destroy + create).
<template>
<Child :key="resetVersion" />
<button @click="resetVersion++">Hard reset Child</button>
</template>
<script setup>
import { ref } from 'vue';
import Child from './Child.vue';
const resetVersion = ref(0);
</script>
Interview-ready takeawayv-if is structural: it creates and destroys DOM and component instances. Toggling it re-runs setup/data and resets local state. Use v-show for frequent toggles, and keep state outside the component (or cache instances where appropriate) when you need persistence.