.agents/skills/vue-best-practices/references/component-keep-alive.md
Impact: HIGH - <KeepAlive> caches component instances instead of destroying them. Use it to preserve state across switches, but manage cache size and freshness explicitly to avoid memory growth or stale UI.
max to cap cache sizeonActivated/onDeactivated for cache-aware logicUse KeepAlive when switching between views where state should persist (tabs, multi-step forms, dashboards). Avoid it when each visit should start fresh.
BAD:
<template>
<!-- State resets on every switch -->
<component :is="currentTab" />
</template>
GOOD:
<template>
<!-- State preserved between switches -->
<KeepAlive>
<component :is="currentTab" />
</KeepAlive>
</template>
Always cap cache size with max and restrict caching to specific components when possible.
<template>
<KeepAlive :max="5" include="Dashboard,Settings">
<component :is="currentView" />
</KeepAlive>
</template>
include and exclude match the component name option. Explicitly set names for reliable caching.
<!-- TabA.vue -->
<script setup>
defineOptions({ name: 'TabA' })
</script>
<template>
<KeepAlive include="TabA,TabB">
<component :is="currentTab" />
</KeepAlive>
</template>
Vue 3 has no direct API to remove a specific cached instance. Use keys or dynamic include/exclude to force refreshes.
<script setup>
import { reactive, ref } from 'vue'
const currentView = ref('Dashboard')
const viewKeys = reactive({ Dashboard: 0, Settings: 0 })
function invalidateCache(view) {
viewKeys[view]++
}
</script>
<template>
<KeepAlive>
<component :is="currentView" :key="`${currentView}-${viewKeys[currentView]}`" />
</KeepAlive>
</template>
Cached components are not destroyed on switch. Use activation hooks for refresh and cleanup.
<script setup>
import { onActivated, onDeactivated } from 'vue'
onActivated(() => {
refreshData()
})
onDeactivated(() => {
pauseTimers()
})
</script>
Decide whether navigation should show cached state or a fresh view. A common pattern is to key by route when params change.
<template>
<router-view v-slot="{ Component, route }">
<KeepAlive>
<component :is="Component" :key="route.fullPath" />
</KeepAlive>
</router-view>
</template>
If you want cache reuse but fresh data, refresh in onActivated and compare query/params before fetching.