KeepAlive — Preserve Component State

Cache Switched Components Instead of Tearing Them Down

KeepAlive — Preserve Component State

`<KeepAlive>` keeps dynamic components mounted in memory when not displayed so their state, inputs, and scroll position survive switching.

4 min read Level 2/5 #vue#keep-alive#performance
What you'll learn
  • Wrap a dynamic component with `<KeepAlive>`
  • Use include / exclude / max
  • Hook into onActivated and onDeactivated

Toggle between two <component :is> components and Vue tears one down and mounts the other — state lost. <KeepAlive> caches them in memory instead so switching is instant and state survives.

Tabbed UI

<script setup lang="ts">
import { ref, shallowRef } from 'vue'
import Posts from './tabs/Posts.vue'
import Settings from './tabs/Settings.vue'

const current = shallowRef(Posts)
</script>

<template>
  <button @click="current = Posts">Posts</button>
  <button @click="current = Settings">Settings</button>

  <KeepAlive>
    <component :is="current" />
  </KeepAlive>
</template>

Type into a search input on Posts, switch to Settings, switch back — your input value is still there.

include / exclude / max

Control which components get cached by component name.

<KeepAlive :include="['Posts', 'Settings']" :max="5">
  <component :is="current" />
</KeepAlive>

max enforces an LRU cap — useful in long-running apps to avoid leaking.

Activation Hooks

Cached components don’t fire onMounted on subsequent shows. Use onActivated / onDeactivated for refresh logic.

import { onActivated, onDeactivated } from 'vue'

onActivated(() => console.log('Posts visible'))
onDeactivated(() => console.log('Posts cached'))

With Router

Keep tabbed router views around too:

<router-view v-slot="{ Component }">
  <KeepAlive>
    <component :is="Component" />
  </KeepAlive>
</router-view>
Transitions & Animations →