在 Vue 3 中实现本地存储(如用户配置数据),主要通过浏览器提供的 localStorage
或 sessionStorage
API。以下是详细实现方案:
基础实现(原生 API)
javascript
复制
下载
// 存储数据
localStorage.setItem('userSettings', JSON.stringify({ theme: 'dark', fontSize: 16 }));
// 读取数据
const settings = JSON.parse(localStorage.getItem('userSettings')) || {};
// 删除数据
localStorage.removeItem('userSettings');
推荐方案:封装响应式存储工具
在 /src/composables/useLocalStorage.js
中创建可复用逻辑:
javascript
复制
下载
import { ref, watchEffect } from 'vue';
export default function useLocalStorage(key, defaultValue) {
// 创建响应式引用
const storedValue = ref(JSON.parse(localStorage.getItem(key)) || defaultValue);
// 监听变化并存储
watchEffect(() => {
localStorage.setItem(key, JSON.stringify(storedValue.value));
});
// 提供清除方法
const clearStorage = () => {
localStorage.removeItem(key);
storedValue.value = defaultValue;
};
return [storedValue, clearStorage];
}
在组件中使用
vue
复制
下载
<script setup>
import { computed } from 'vue';
import useLocalStorage from '@/composables/useLocalStorage';
// 使用存储钩子(带默认值)
const [userSettings, clearSettings] = useLocalStorage('userConfig', {
theme: 'light',
fontSize: 14,
notifications: true
});
// 修改配置
const toggleTheme = () => {
userSettings.value.theme = userSettings.value.theme === 'light' ? 'dark' : 'light';
};
// 计算属性示例
const themeClass = computed(() => `theme-${userSettings.value.theme}`);
</script>
<template>
<div :class="themeClass">
<button @click="toggleTheme">切换主题</button>
<button @click="clearSettings">重置配置</button>
<input
type="range"
min="12" max="24"
v-model.number="userSettings.fontSize"
>
</div>
</template>
高级技巧
-
存储加密(敏感数据):
javascript
复制
下载
import CryptoJS from 'crypto-js'; const SECRET_KEY = import.meta.env.VITE_STORAGE_SECRET; // 加密存储 const encryptedData = CryptoJS.AES.encrypt( JSON.stringify(data), SECRET_KEY ).toString(); // 解密读取 const bytes = CryptoJS.AES.decrypt(storedData, SECRET_KEY); const originalData = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
-
类型安全存取:
javascript
复制
下载
// 增强版存储方法 const typedStorage = { get(key, type = 'string') { const value = localStorage.getItem(key); if (value === null) return null; try { return { 'number': Number(value), 'boolean': value === 'true', 'object': JSON.parse(value), 'array': JSON.parse(value) }[type] || value; } catch { return value; } }, set(key, value) { const type = typeof value; const toStore = ['object', 'array'].includes(type) ? JSON.stringify(value) : value; localStorage.setItem(key, toStore); } };
注意事项
-
存储限制:
-
单个域名存储上限通常为 5MB
-
单个键值对建议不超过 2MB
-
-
最佳实践:
javascript
复制
下载
// 1. 添加存储版本控制 const STORAGE_VERSION = 'v1'; const storageKey = `${STORAGE_VERSION}_userConfig`; // 2. 添加存储错误处理 try { localStorage.setItem(key, data); } catch (e) { console.error('存储失败:', e); // 降级方案:使用 sessionStorage 或内存存储 } // 3. 监听跨标签页更新 window.addEventListener('storage', (event) => { if (event.key === storageKey) { // 更新本地数据 userSettings.value = JSON.parse(event.newValue); } });
-
替代方案选择:
方案 特点 适用场景 localStorage 永久存储 用户配置、长期数据 sessionStorage 标签页关闭即清除 临时表单数据 IndexedDB 大容量存储 (250MB+) 离线应用、大型数据 Cookies 自动携带到请求头 身份认证
完整示例(TypeScript 版)
typescript
复制
下载
// useLocalStorage.ts
import { ref, watch, Ref } from 'vue';
type StorageValue<T> = Ref<T>;
export default function useLocalStorage<T>(
key: string,
defaultValue: T
): [StorageValue<T>, () => void] {
const storedValue = ref(defaultValue) as StorageValue<T>;
// 初始化读取
try {
const item = localStorage.getItem(key);
if (item !== null) {
storedValue.value = JSON.parse(item);
}
} catch (error) {
console.error(`读取 ${key} 失败:`, error);
}
// 监听变化
watch(storedValue, (newVal) => {
try {
localStorage.setItem(key, JSON.stringify(newVal));
} catch (error) {
console.error(`存储 ${key} 失败:`, error);
}
}, { deep: true });
const clear = () => {
localStorage.removeItem(key);
storedValue.value = defaultValue;
};
return [storedValue, clear];
}
通过这种方式,您可以:
-
创建响应式的持久化存储
-
自动同步 localStorage 变化
-
支持复杂对象存储
-
提供类型安全(TypeScript)
-
处理存储异常情况