🎭 The Magic Memory Box: Vue’s KeepAlive Component
Once Upon a Time in Component Land…
Imagine you have a magic toy box. Every time you take out a toy to play, you set it up exactly how you like it. But when you put it away and take out another toy, then come back—your first toy has forgotten everything! You have to set it up all over again. 😢
What if the toy box could remember? What if it kept your toys exactly how you left them?
That’s exactly what Vue’s <KeepAlive> does for your components!
🏠 What is KeepAlive?
Think of <KeepAlive> as a cozy blanket that wraps around your components. When you switch away from a component, instead of destroying it completely, Vue tucks it under the blanket to sleep. When you come back, it wakes up—exactly as you left it!
Without KeepAlive (The Forgetful Box)
<component :is="currentTab">
</component>
Every time you switch tabs, Vue:
- ❌ Destroys the old component
- ❌ Forgets all its data
- ❌ Creates a brand new one
With KeepAlive (The Memory Box)
<KeepAlive>
<component :is="currentTab">
</component>
</KeepAlive>
Now Vue:
- ✅ Keeps the component alive in memory
- ✅ Remembers all its data
- ✅ Just wakes it up when needed
🎪 Real-Life Example
Imagine you’re filling out a long form on a website. You switch to another tab to check something. When you come back…
Without KeepAlive: 😱 All your form data is GONE!
With KeepAlive: 😊 Everything is still there, exactly as you left it!
graph TD A["User on Form Page"] --> B{Switches Tab} B -->|Without KeepAlive| C["Form Destroyed"] C --> D["Data Lost Forever"] B -->|With KeepAlive| E["Form Hidden But Alive"] E --> F["Data Safe & Sound"]
🎯 Include & Exclude: Choosing Who Gets the Magic
Not every component needs to stay alive. Some are tiny and quick to recreate. Others hold precious data.
Include = “Only these components get the magic blanket” Exclude = “Everyone EXCEPT these gets the magic blanket”
Using Include (Allowlist)
<!-- Only CompA gets remembered -->
<KeepAlive include="CompA">
<component :is="currentTab">
</component>
</KeepAlive>
<!-- Multiple components -->
<KeepAlive include="CompA,CompB">
<component :is="currentTab">
</component>
</KeepAlive>
<!-- Using regex -->
<KeepAlive :include="/Comp(A|B)/">
<component :is="currentTab">
</component>
</KeepAlive>
Using Exclude (Blocklist)
<!-- Everyone EXCEPT CompC gets remembered -->
<KeepAlive exclude="CompC">
<component :is="currentTab">
</component>
</KeepAlive>
Using an Array
<KeepAlive :include="['CompA', 'CompB']">
<component :is="currentTab">
</component>
</KeepAlive>
graph TD A["KeepAlive"] --> B{include or exclude?} B -->|include='CompA'| C["Only CompA cached"] B -->|exclude='CompC'| D["All except CompC cached"] B -->|Neither| E["All components cached"]
📦 Max Cached Instances: Don’t Overstuff the Box!
Imagine your magic box can only hold 3 toys at a time. If you try to add a 4th, the oldest one has to go!
This is what max does. It prevents your app from using too much memory.
<!-- Only keep the 5 most recent components -->
<KeepAlive :max="5">
<component :is="currentTab">
</component>
</KeepAlive>
How It Works (LRU Cache)
LRU = Least Recently Used
When the box is full and a new component needs space:
- Vue looks at which cached component was used longest ago
- That component gets removed
- The new component takes its place
graph TD A["Max = 3 Components"] --> B["Cache: A, B, C"] B --> C{New Component D arrives} C --> D["A is oldest/least used"] D --> E["Remove A from cache"] E --> F["Cache: B, C, D"]
Example Scenario
max="3"
User visits: Home → Profile → Settings → About
Cache states:
1. [Home]
2. [Home, Profile]
3. [Home, Profile, Settings]
4. [Profile, Settings, About] ← Home removed!
🎭 KeepAlive Lifecycle Hooks: Knowing When to Wake & Sleep
When a component is cached, it doesn’t get destroyed. So mounted and unmounted don’t fire when switching!
Instead, Vue gives us two special hooks:
🌟 onActivated - “Good Morning!”
Called when a cached component becomes visible again.
🌙 onDeactivated - “Good Night!”
Called when a component is being cached (hidden but not destroyed).
<script setup>
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {
console.log('I am awake! 🌞')
// Good time to:
// - Refresh data
// - Start timers
// - Resume animations
})
onDeactivated(() => {
console.log('Going to sleep... 💤')
// Good time to:
// - Pause timers
// - Stop animations
// - Save scroll position
})
</script>
When Do They Fire?
graph TD A["Component Created"] --> B["mounted fires"] B --> C["Component Visible"] C --> D{User switches away} D -->|With KeepAlive| E["onDeactivated fires"] E --> F["Component cached"] F --> G{User comes back} G --> H["onActivated fires"] H --> C D -->|Without KeepAlive| I["unmounted fires"] I --> J["Component destroyed"]
Complete Lifecycle with KeepAlive
| Event | Normal Component | Cached Component |
|---|---|---|
| First appears | mounted |
mounted + onActivated |
| Hidden | unmounted |
onDeactivated |
| Shows again | mounted (new!) |
onActivated |
| Removed from cache | - | onDeactivated + unmounted |
🎨 Putting It All Together
Here’s a complete example showing everything working together:
<template>
<div class="tabs">
<button
v-for="tab in tabs"
:key="tab"
@click="currentTab = tab">
{{ tab }}
</button>
</div>
<KeepAlive
:include="['FormPage', 'Dashboard']"
:max="3">
<component :is="currentTab">
</component>
</KeepAlive>
</template>
<script setup>
import { ref } from 'vue'
const currentTab = ref('Dashboard')
const tabs = [
'Dashboard',
'FormPage',
'Settings'
]
</script>
💡 Quick Tips to Remember
| Situation | Solution |
|---|---|
| Form data disappearing | Wrap in <KeepAlive> |
| Too much memory usage | Use :max="number" |
| Only cache specific components | Use include |
| Cache all except some | Use exclude |
| Need to run code when switching | Use onActivated/onDeactivated |
🎯 The Golden Rules
- Use KeepAlive when switching between components that hold state
- Set a max to prevent memory problems
- Use include/exclude to be selective
- Use lifecycle hooks to manage timers and data refresh
You’ve now mastered the Magic Memory Box! Your components will never forget again! 🎉
