Persistent storage solution
Local Storage Solutions
Common local persistent storage solutions in Vue.js applications include localStorage and sessionStorage. Both are based on the Web Storage API and provide a simple key-value storage mechanism.
// Store data
localStorage.setItem('userToken', 'abc123def456')
sessionStorage.setItem('currentTab', 'profile')
// Retrieve data
const token = localStorage.getItem('userToken')
const activeTab = sessionStorage.getItem('currentTab')
// Delete data
localStorage.removeItem('userToken')
sessionStorage.clear()
Characteristics of localStorage:
- Storage capacity of approximately 5MB
- Data is permanently saved unless manually cleared
- Restricted by same-origin policy
- Synchronous operations may block the main thread
Key differences between sessionStorage and localStorage:
- Data is only valid for the current session
- Automatically cleared when the tab is closed
- Isolated between different tabs
IndexedDB Solution
For scenarios requiring storage of large amounts of structured data, IndexedDB provides a more powerful solution:
// Open or create a database
const request = indexedDB.open('MyDatabase', 1)
request.onupgradeneeded = (event) => {
const db = event.target.result
const store = db.createObjectStore('products', { keyPath: 'id' })
store.createIndex('priceIdx', 'price', { unique: false })
}
request.onsuccess = (event) => {
const db = event.target.result
const transaction = db.transaction('products', 'readwrite')
const store = transaction.objectStore('products')
// Add data
store.add({ id: 1, name: 'Laptop', price: 999 })
// Query data
const getRequest = store.get(1)
getRequest.onsuccess = () => {
console.log(getRequest.result)
}
}
Advantages of IndexedDB:
- Supports transactional operations
- Supports indexed queries
- Storage capacity is much larger than localStorage
- Asynchronous operations do not block the UI
- Supports binary data storage
Vuex Persistence Plugin
For Vuex state management, the vuex-persistedstate plugin can be used to achieve state persistence:
import createPersistedState from 'vuex-persistedstate'
const store = new Vuex.Store({
// ...
plugins: [
createPersistedState({
key: 'my-vuex-store',
storage: window.localStorage,
reducer: (state) => ({
user: state.user,
settings: state.settings
}),
paths: ['user.authToken']
})
]
})
Configuration options:
key
: The key name used for storagestorage
: Specifies the storage medium (localStorage/sessionStorage)reducer
: Customizes the state to be persistedpaths
: Specifies the module paths to be persisted
Cookie Storage Solution
Although modern frontend development rarely directly manipulates cookies, they are still useful in certain scenarios:
// Set Cookie
document.cookie = `username=john; expires=${new Date(Date.now() + 86400000).toUTCString()}; path=/`
// Read Cookie
function getCookie(name) {
const value = `; ${document.cookie}`
const parts = value.split(`; ${name}=`)
if (parts.length === 2) return parts.pop().split(';').shift()
}
Characteristics of cookies:
- Maximum of 50 per domain
- Single cookie size limited to 4KB
- Included in every HTTP request
- Supports expiration time settings
- Restricted by same-origin policy
File System Access API
Modern browsers provide the File System Access API, suitable for handling user files:
async function saveFile(content) {
try {
const handle = await window.showSaveFilePicker({
types: [{
description: 'Text Files',
accept: { 'text/plain': ['.txt'] }
}]
})
const writable = await handle.createWritable()
await writable.write(content)
await writable.close()
return handle
} catch (err) {
console.error('Error saving file:', err)
}
}
Main features include:
- Reading local file content
- Saving modifications to the original file
- Creating and saving new files
- Listing directory contents
- Requires user interaction
Server-Side Synchronized Storage
Combining Axios for synchronized storage with the server:
import axios from 'axios'
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000
})
// Encapsulated storage methods
const storage = {
async set(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value))
await api.post('/sync', { key, value })
} catch (error) {
console.error('Sync failed:', error)
}
},
async get(key) {
const localValue = localStorage.getItem(key)
if (!localValue) {
try {
const { data } = await api.get(`/sync?key=${key}`)
return data.value
} catch (error) {
console.error('Fetch failed:', error)
return null
}
}
return JSON.parse(localValue)
}
}
// Usage example
storage.set('preferences', { theme: 'dark', fontSize: 14 })
.then(() => storage.get('preferences'))
.then(prefs => console.log(prefs))
Encrypted Storage Solution
For sensitive data, encrypted storage is recommended:
import CryptoJS from 'crypto-js'
const SECRET_KEY = 'my-secret-key-123'
const secureStorage = {
encrypt(data) {
return CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY).toString()
},
decrypt(ciphertext) {
const bytes = CryptoJS.AES.decrypt(ciphertext, SECRET_KEY)
return JSON.parse(bytes.toString(CryptoJS.enc.Utf8))
},
set(key, value) {
localStorage.setItem(key, this.encrypt(value))
},
get(key) {
const ciphertext = localStorage.getItem(key)
return ciphertext ? this.decrypt(ciphertext) : null
}
}
// Usage example
secureStorage.set('auth', { token: 'xyz789', expires: 3600 })
const authData = secureStorage.get('auth')
Storage Strategy Selection
Recommendations for storage solutions in different scenarios:
- User Preferences: localStorage + Vuex persistence plugin
- Shopping Cart Data: sessionStorage + server-side backup
- Large Datasets: IndexedDB
- Sensitive Information: Encrypted storage + short-term cookies
- Offline Application Data: IndexedDB + Service Worker caching
Performance Optimization Tips
Performance optimization suggestions for storage operations:
// Batch operations instead of multiple single operations
function batchSave(items) {
const transaction = db.transaction('items', 'readwrite')
const store = transaction.objectStore('items')
items.forEach(item => {
store.put(item)
})
return new Promise((resolve, reject) => {
transaction.oncomplete = resolve
transaction.onerror = reject
})
}
// Use Web Workers for large data processing
const worker = new Worker('storage-worker.js')
worker.postMessage({
action: 'BULK_INSERT',
data: largeDataSet
})
Other optimization techniques:
- Add an in-memory cache layer for frequently read data
- Use debounce to merge frequent write operations
- Store and read large data in chunks
- Regularly clean up expired data
Cross-Tab Communication
Using storage events for communication between tabs:
// Sender
localStorage.setItem('message', JSON.stringify({
type: 'DATA_UPDATE',
payload: { /* data */ },
timestamp: Date.now()
}))
// Receiver
window.addEventListener('storage', (event) => {
if (event.key === 'message') {
const message = JSON.parse(event.newValue)
if (message.type === 'DATA_UPDATE') {
// Handle data updates
}
}
})
Storage Limit Handling
Handling insufficient storage space:
function checkStorageSpace() {
if ('storage' in navigator && 'estimate' in navigator.storage) {
return navigator.storage.estimate()
.then(estimate => {
const remaining = estimate.quota - estimate.usage
return remaining > 1024 * 1024 // Reserve 1MB space
})
}
return Promise.resolve(true)
}
async function safeSetItem(key, value) {
const hasSpace = await checkStorageSpace()
if (!hasSpace) {
await clearOldData()
}
localStorage.setItem(key, value)
}
function clearOldData() {
// Implement LRU strategy for clearing old data
}
Storage Data Migration
Implementing data migration during storage solution upgrades:
function migrateLocalStorageToIndexedDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('AppDatabase', 2)
request.onupgradeneeded = (event) => {
const db = event.target.result
if (!db.objectStoreNames.contains('legacyData')) {
const store = db.createObjectStore('legacyData')
// Migrate localStorage data
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i)
store.put(localStorage.getItem(key), key)
}
}
}
request.onsuccess = () => {
// Clear old data after migration
localStorage.clear()
resolve()
}
request.onerror = reject
})
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:服务端渲染支持
下一篇:TypeScript深度集成