963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
4.6 KiB
4.6 KiB
title, impact, impactDescription, type, tags
| title | impact | impactDescription | type | tags | |||||
|---|---|---|---|---|---|---|---|---|---|
| Vue 3 KeepAlive Has No Direct Cache Removal API | MEDIUM | Unlike Vue 2, there is no way to programmatically remove a specific component from KeepAlive cache in Vue 3 | gotcha |
|
Vue 3 KeepAlive Has No Direct Cache Removal API
Impact: MEDIUM - Vue 3 removed the $destroy() method that Vue 2 developers used to indirectly clear KeepAlive cache entries. There is no direct API to remove a specific cached component in Vue 3.
Task Checklist
- Do not rely on programmatic cache removal from Vue 2 patterns
- Use
include/excludeprops for dynamic cache control - Use key changes to force cache invalidation
- Set appropriate
maxprop to auto-evict old entries
The Problem
Vue 2 Pattern (No Longer Works)
// Vue 2: Could destroy specific component instance
this.$children[0].$destroy();
Vue 3: No Equivalent API
// Vue 3: $destroy() does not exist
// There is NO direct way to remove a specific cached instance
Solutions
Solution 1: Dynamic Include/Exclude
Control cache membership via reactive props:
<script setup>
import { ref, computed } from 'vue';
const cachedViews = ref(['Dashboard', 'Settings', 'Profile']);
function removeFromCache(viewName) {
cachedViews.value = cachedViews.value.filter((v) => v !== viewName);
}
function addToCache(viewName) {
if (!cachedViews.value.includes(viewName)) {
cachedViews.value.push(viewName);
}
}
</script>
<template>
<KeepAlive :include="cachedViews">
<component :is="currentView" />
</KeepAlive>
</template>
When a component is removed from include, it will be destroyed on next switch.
Solution 2: Key-Based Cache Invalidation
Change the key to force a fresh instance:
<script setup>
import { ref, reactive } from 'vue';
const currentView = ref('Dashboard');
const viewKeys = reactive({
Dashboard: 0,
Settings: 0,
Profile: 0,
});
function invalidateCache(viewName) {
viewKeys[viewName]++;
}
function switchView(viewName) {
currentView.value = viewName;
}
// Force fresh Dashboard on next visit
function refreshDashboard() {
invalidateCache('Dashboard');
}
</script>
<template>
<KeepAlive>
<component :is="currentView" :key="`${currentView}-${viewKeys[currentView]}`" />
</KeepAlive>
</template>
Solution 3: Conditional KeepAlive
Wrap or unwrap based on cache need:
<script setup>
import { ref } from 'vue';
const currentView = ref('Dashboard');
const shouldCache = ref(true);
function clearCacheAndSwitch(viewName) {
shouldCache.value = false;
currentView.value = viewName;
// Re-enable caching after the switch
nextTick(() => {
shouldCache.value = true;
});
}
</script>
<template>
<KeepAlive v-if="shouldCache">
<component :is="currentView" />
</KeepAlive>
<component v-else :is="currentView" />
</template>
Solution 4: Use Max for Automatic Eviction
Let LRU cache handle cleanup:
<template>
<!-- Automatically evicts least recently used when cache is full -->
<KeepAlive :max="5">
<component :is="currentView" />
</KeepAlive>
</template>
Vue Router: Clear Cache on Certain Navigations
<script setup>
import { ref, watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const cachedRoutes = ref(['Dashboard', 'Settings']);
// Clear specific route from cache when navigating from certain paths
watch(
() => route.name,
(newRoute, oldRoute) => {
if (oldRoute === 'Login') {
// User just logged in - clear and refresh Dashboard
cachedRoutes.value = cachedRoutes.value.filter((r) => r !== 'Dashboard');
nextTick(() => {
cachedRoutes.value.push('Dashboard');
});
}
},
);
</script>
<template>
<router-view v-slot="{ Component }">
<KeepAlive :include="cachedRoutes">
<component :is="Component" />
</KeepAlive>
</router-view>
</template>
Key Points
- No
$destroy()in Vue 3 - Cannot directly remove cached instances - Use dynamic
include- Reactively control which components are cached - Use key changes - Changing key creates a new cache entry
- Use
maxprop - LRU eviction handles cleanup automatically - Plan cache strategy - Design around these constraints upfront