DEV Community

Cover image for Preserve Component State in Vue with KeepAlive
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

Preserve Component State in Vue with KeepAlive

When building Vue applications, we often switch between different components like tabs, multi-step forms, dynamic components, or event different views inside the same page.

By default, when Vue removes a component from the DOM, its component instance is also unmounted. When you render it again, Vue creates a completely new instance.

This means that things like local state, form input, or component state can be lost.

This is where <KeepAlive> becomes incredibly useful. Vue's KeepAlive component allows you to cache inactive component instances instead of destroying them.

In this article, we'll explore:

  • What KeepAlive is
  • What problem it solves
  • How to use it with dynamic components
  • How to control which components are cached
  • How onActivated and onDeactivated work
  • Common mistakes and best practices

Let's dive in.

🤔 What Is Vue KeepAlive?

<KeepAlive> is a built-in Vue component that allows you to cache component instances when they are switched out.

Consider a simple dynamic component:

<script setup lang="ts">
import { ref } from 'vue'

import Profile from './Profile.vue'
import Settings from './Settings.vue'

const currentComponent = ref(Profile)
</script>

<template>
  <button @click="currentComponent = Profile">
    Profile
  </button>

  <button @click="currentComponent = Settings">
    Settings
  </button>

  <component :is="currentComponent" />
</template>
Enter fullscreen mode Exit fullscreen mode

When you switch from Profile to Settings, the Profile component is unmounted.

When you switch back, Vue creates a new Profile instance.

Now let's add KeepAlive:

<KeepAlive>
  <component :is="currentComponent" />
</KeepAlive>
Enter fullscreen mode Exit fullscreen mode

Now Vue keeps the inactive component instance alive.

Instead of:

Profile
  ↓
Unmount
  ↓
Destroy state
Enter fullscreen mode Exit fullscreen mode

you get:

Profile
  ↓
Deactivated
  ↓
Cached
  ↓
Activated again
Enter fullscreen mode Exit fullscreen mode

The component state is preserved.

🟢 What Problem Does KeepAlive Solve?

Imagine you have a tabbed interface.

Profile | Settings | Billing
Enter fullscreen mode Exit fullscreen mode

Inside the Profile tab, the user fills out a form:

Name: John
Email: john@example.com
Enter fullscreen mode Exit fullscreen mode

Then they switch to Settings.

Without KeepAlive, the Profile component can be unmounted.

When they return:

Name:
Email:
Enter fullscreen mode Exit fullscreen mode

The form has been reset.

That's a terrible user experience.

With KeepAlive:

Profile
  ↓
User enters data
  ↓
Switch to Settings
  ↓
Profile is cached
  ↓
Return to Profile
  ↓
Form state is preserved
Enter fullscreen mode Exit fullscreen mode

This is one of the most common use cases for KeepAlive.

🟢 Using KeepAlive with Dynamic Components

The most common pattern is wrapping a dynamic component.

<KeepAlive>
  <component :is="currentComponent" />
</KeepAlive>
Enter fullscreen mode Exit fullscreen mode

For example:

<script setup lang="ts">
import { ref } from 'vue'

import Dashboard from './Dashboard.vue'
import Analytics from './Analytics.vue'

const currentComponent = ref(Dashboard)
</script>

<template>
  <nav>
    <button @click="currentComponent = Dashboard">
      Dashboard
    </button>

    <button @click="currentComponent = Analytics">
      Analytics
    </button>
  </nav>

  <KeepAlive>
    <component :is="currentComponent" />
  </KeepAlive>
</template>
Enter fullscreen mode Exit fullscreen mode

Now both components can preserve their internal state when switching between them.

This works especially well for:

  • tabs
  • dashboards
  • editors
  • multi-step forms
  • complex filters

🟢 KeepAlive and Lifecycle Hooks

When using KeepAlive, the normal lifecycle changes slightly.

A cached component is not unmounted when it becomes inactive.

Instead, Vue provides two special lifecycle hooks:

onActivated()
Enter fullscreen mode Exit fullscreen mode

and:

onDeactivated()
Enter fullscreen mode Exit fullscreen mode

For example:

<script setup lang="ts">
import {
  onActivated,
  onDeactivated
} from 'vue'

onActivated(() => {
  console.log('Component is active')
})

onDeactivated(() => {
  console.log('Component is inactive')
})
</script>
Enter fullscreen mode Exit fullscreen mode

This can be useful when you need to perform actions whenever the component becomes visible or hidden.

For example:

  • refresh data
  • restart an animation
  • pause a timer
  • reconnect to a resource
  • update UI state

🟢 KeepAlive vs onMounted

One important thing to understand is that onMounted() doesn't run every time a cached component becomes visible.

Consider:

onMounted(() => {
  console.log('mounted')
})

onActivated(() => {
  console.log('activated')
})
Enter fullscreen mode Exit fullscreen mode

The lifecycle looks roughly like this:

First visit
↓
onMounted()
↓
onActivated()

Switch away
↓
onDeactivated()

Return
↓
onActivated()
Enter fullscreen mode Exit fullscreen mode

The component remains mounted while it is cached.

This distinction is important when working with data fetching or subscriptions.

🟢 Controlling Which Components Are Cached

You don't always want to cache everything.

Vue allows you to control the cache using include and exclude.

For example:

<KeepAlive include="Profile,Settings">
  <component :is="currentComponent" />
</KeepAlive>
Enter fullscreen mode Exit fullscreen mode

Only components matching those names will be cached.

You can also exclude components:

<KeepAlive exclude="HeavyChart">
  <component :is="currentComponent" />
</KeepAlive>
Enter fullscreen mode Exit fullscreen mode

This is useful when some components are expensive to keep in memory.

🟢 Limiting the Cache with max

KeepAlive also supports a max prop.

<KeepAlive :max="5">
  <component :is="currentComponent" />
</KeepAlive>
Enter fullscreen mode Exit fullscreen mode

This limits the number of component instances kept in the cache.

When the limit is reached, Vue removes the least recently used cached component.

This is particularly useful for applications where users can navigate through many dynamic views.

🟢 KeepAlive Isn't Always the Right Choice

Caching components sounds great, but it comes with a cost.

A cached component still exists in memory.

If you cache many complex components, you can increase memory usage.

For example:

100 cached dashboards
+
large charts
+
large reactive state
=
potentially expensive memory usage
Enter fullscreen mode Exit fullscreen mode

That's why KeepAlive should be used intentionally.

Ask yourself:

👉 "Does preserving this component's state provide enough value to justify keeping it in memory?"

If the answer is no, regular mounting and unmounting may be better.

🧪 Best Practices

  • Use KeepAlive when preserving component state improves UX
  • Prefer it for tabs, editors, forms, and complex dynamic views
  • Use include and exclude when only some components should be cached
  • Use max when users can create many cached component instances
  • Use onActivated for logic that should run whenever a cached component becomes active
  • Use onDeactivated to pause timers, subscriptions, or other ongoing work
  • Be careful when caching memory-heavy components
  • Don't use KeepAlive everywhere just because it is available

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

🧪 Advance skills

A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.

Check out Certificates.dev by clicking this link or by clicking the image below:

Certificates.dev Link

Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!

✅ Summary

Vue's KeepAlive is a powerful built-in component for preserving state between dynamic component switches.

In this article, you learned:

  • What KeepAlive is
  • How it preserves component instances
  • How to use it with dynamic components
  • How onActivated and onDeactivated work
  • How to control caching with include, exclude, and max
  • When caching components can become a performance concern

KeepAlive is especially useful when users expect their state to remain intact while navigating between views.

Use it intentionally, cache the components that benefit from it, and avoid keeping large numbers of memory-heavy components alive unnecessarily.

Take care!
And happy coding as always 🖥️

Top comments (0)