Vue3本地存储实现方案
在 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)
-
处理存储异常情况