Frontend Caching System โ
MineAdmin's frontend provides a comprehensive caching system, including multi-layer caching strategies such as page caching, data caching, and browser storage caching. Proper use of caching mechanisms can significantly enhance application performance and user experience.
Overview of Cache Types โ
- Page Caching: Based on Vue's
keep-alive
mechanism to cache page component states - Data Caching: Caches API request results and user data
- Storage Caching: Persistent caching based on localStorage/sessionStorage
- Route Caching: Caches route states and tab information
Page Caching (Keep-Alive) โ
Page caching is implemented using Vue's keep-alive
mechanism to cache page component states, avoiding repeated rendering and data requests.
Enabling Page Caching โ
To enable page caching, the following three conditions must be met:
- Set Route Meta Information: Set the
meta.cache
property of the route totrue
- Define Component Name: Use
defineOptions
to define the component name in the page component - Maintain Single Root Node: The page template must have exactly one root node
Implementation Example โ
<script setup lang="ts">
// Define the component name, which must match the route's name property
defineOptions({
name: 'UserManagement' // Corresponds to route name: 'UserManagement'
})
// Page logic
const userList = ref([])
const searchForm = ref({})
// Page data will be cached, maintaining its state when users switch back to the tab
</script>
<template>
<!-- Must maintain a single root node -->
<div class="user-management-page">
<ma-table
ref="tableRef"
:columns="columns"
:data="userList"
:search="searchForm"
/>
</div>
</template>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Route Configuration โ
Static Routes โ
// src/router/static-routes/userRoute.ts
export default {
name: 'UserManagement',
path: '/user/management',
component: () => import('@/views/user/management/index.vue'),
meta: {
title: 'User Management',
cache: true, // Enable caching
icon: 'i-heroicons:users',
type: 'M'
}
}
2
3
4
5
6
7
8
9
10
11
12
Dynamic Routes (Menu Management) โ
For dynamic routes generated through backend menu management, you can set the cache property in the menu management interface:
- Navigate to System Management โ Menu Management
- Edit the corresponding menu item
- Find the Enable Cache toggle in the form
- Enable it and save
Reference menu form implementation: menu-form.vue#L175
Caching Mechanism Principle โ
The system implements page caching through the following methods:
- Route Guard Detection: Checks the
meta.cache
property inrouter.afterEach
- Component Name Collection: Collects the
name
property of page components and adds it to the cache list - Keep-Alive Wrapping: Uses
<KeepAlive>
in the layout component to wrap the route view
Core implementation code:
// src/router/index.ts
router.afterEach(async (to) => {
const keepAliveStore = useKeepAliveStore()
// Check if caching is needed and not an iframe page
if (to.meta.cache && to.meta.type !== 'I') {
const componentName = to.matched.at(-1)?.components?.default!.name
if (componentName) {
keepAliveStore.add(componentName) // Add to cache list
} else {
console.warn(`Component page does not have a component name set and will not be cached`)
}
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/layouts/index.tsx
<RouterView>
{({ Component }) => (
<Transition name={appSetting.pageAnimate} mode="out-in">
<KeepAlive include={keepAliveStore.list}>
{(keepAliveStore.getShowState() && route.meta.type !== 'I') &&
<Component key={route.fullPath} />
}
</KeepAlive>
</Transition>
)}
</RouterView>
2
3
4
5
6
7
8
9
10
11
12
Cache Management โ
Disabling Page Caching โ
There are several ways to disable page caching:
- Do Not Set Cache Property (Recommended)
// Do not set cache or set it to false in route configuration
meta: {
title: 'Temporary Page',
cache: false // Or omit this property
}
2
3
4
5
- Do Not Define Component Name
<script setup lang="ts">
// Do not use defineOptions to define component name
// Even if route has cache: true, it won't be cached
</script>
2
3
4
Clearing Page Cache โ
The system provides multiple methods to clear caches:
// Get keep-alive store instance
const keepAliveStore = useKeepAliveStore()
// 1. Remove specified page cache
keepAliveStore.remove('UserManagement')
// 2. Remove multiple page caches
keepAliveStore.remove(['UserManagement', 'RoleManagement'])
// 3. Clear all page caches
keepAliveStore.clean()
// 4. Temporarily hide cache (for page refresh)
keepAliveStore.hidden()
// Restore cache display
keepAliveStore.display()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Tab Cache Management โ
The tab system is tightly integrated with page caching, providing complete cache lifecycle management:
const tabStore = useTabStore()
// Refresh current tab (clears and reloads cache)
await tabStore.refreshTab()
// Automatically clears corresponding page cache when closing tab
tabStore.closeTab(targetTab)
// Close other tabs (preserves fixed tabs and current tab cache)
await tabStore.closeOtherTab(currentTab)
2
3
4
5
6
7
8
9
10
Data Caching (Web Storage) โ
In addition to page caching, MineAdmin provides a powerful data caching system for caching API data, user preferences, and other information.
useCache Hook โ
The system provides the useCache
Hook to uniformly manage browser storage:
import useCache from '@/hooks/useCache'
// Use localStorage (default)
const localStorage = useCache('localStorage')
// Use sessionStorage
const sessionStorage = useCache('sessionStorage')
2
3
4
5
6
7
Basic Usage โ
const cache = useCache()
// Store data
cache.set('userInfo', {
id: 1,
name: 'admin',
roles: ['admin']
})
// Store data with expiration (in seconds)
cache.set('tempData', { value: 'temp' }, { exp: 3600 }) // Expires in 1 hour
// Retrieve data
const userInfo = cache.get('userInfo')
const tempData = cache.get('tempData', null) // Provide default value
// Remove data
cache.remove('tempData')
// Remove all expired data
cache.removeAllExpires()
// Update data expiration
cache.touch('userInfo', 7200) // Extend by 2 hours
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Advanced Features โ
Automatic Prefix โ
All cache keys automatically include an application prefix to avoid conflicts with other apps:
// Actual stored key will be: VITE_APP_STORAGE_PREFIX + 'userInfo'
cache.set('userInfo', data)
2
Capacity Management โ
When storage is low, the system automatically cleans expired data:
cache.set('largeData', data, {
exp: 3600,
force: true // Force storage by cleaning expired data when capacity is low
})
2
3
4
Application in HTTP Requests โ
The system uses caching in HTTP interceptors to store user authentication information:
// src/utils/http.ts
const cache = useCache()
const userStore = useUserStore()
// Store authentication tokens
cache.set('token', data.access_token)
cache.set('expire', useDayjs().unix() + data.expire_at, { exp: data.expire_at })
cache.set('refresh_token', data.refresh_token)
// Read cache when automatically refreshing tokens
if (!cache.get('refresh_token')) {
await logout()
}
2
3
4
5
6
7
8
9
10
11
12
13
Caching Best Practices โ
1. Proper Use of Page Caching โ
- Suitable for caching: List pages, form pages, detail pages
- Not suitable for caching: Login pages, error pages, temporary popup pages
- Notes: Ensure unique component names to avoid cache conflicts
2. Data Caching Strategies โ
// Cache dictionary data (long-term)
cache.set('dictData', dictList, { exp: 24 * 3600 }) // 24 hours
// Cache user preferences (persistent)
cache.set('userSettings', settings) // No expiration
// Cache temporary state (short-term)
cache.set('searchForm', formData, { exp: 1800 }) // 30 minutes
2
3
4
5
6
7
8
3. Cache Cleaning Strategies โ
// Clear sensitive data on logout
function logout() {
cache.remove('token')
cache.remove('refresh_token')
cache.remove('userInfo')
// Clear page caches
keepAliveStore.clean()
tabStore.clearTab()
}
// Regularly clean expired data
setInterval(() => {
cache.removeAllExpires()
}, 60 * 60 * 1000) // Clean every hour
2
3
4
5
6
7
8
9
10
11
12
13
14
15
4. Performance Optimization Suggestions โ
- Avoid caching overly large data objects
- Set reasonable expiration times to prevent memory leaks
- Consider using sessionStorage for frequently updated data
- Monitor cache usage and clean unnecessary caches promptly
Frequently Asked Questions โ
Issue 1: Page Caching Not Working โ
Possible Causes:
- Component does not define
name
property - Route
meta.cache
is not set totrue
- Page template has multiple root nodes
Solution:
<!-- Incorrect example: Multiple root nodes -->
<template>
<div>Content 1</div>
<div>Content 2</div>
</template>
<!-- Correct example: Single root node -->
<template>
<div>
<div>Content 1</div>
<div>Content 2</div>
</div>
</template>
2
3
4
5
6
7
8
9
10
11
12
13
Issue 2: Cached Data Expired โ
// Check if data exists and is not expired
const cachedData = cache.get('userData')
if (!cachedData) {
// Re-fetch data
const newData = await fetchUserData()
cache.set('userData', newData, { exp: 3600 })
}
2
3
4
5
6
7
Issue 3: Excessive Cache Usage โ
// Regularly clean and monitor cache usage
function monitorCacheUsage() {
try {
const used = JSON.stringify(localStorage).length
const quota = 5 * 1024 * 1024 // 5MB limit
if (used > quota * 0.8) {
console.warn('Cache usage too high, recommend cleaning')
cache.removeAllExpires()
}
} catch (error) {
console.error('Cache monitoring failed', error)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
Source Code References โ
- useCache Hook - Data caching utility
- useKeepAliveStore - Page cache state management
- useTabStore - Tab cache management
- Router Configuration - Route caching logic
- Layout Implementation - Keep-Alive implementation