1. 为什么需要浏览器存储?
在前端开发中,数据的持久化存储是刚需场景。用户的主题偏好、表单草稿、购物车信息等数据都需要在页面刷新甚至关闭后依然存在。传统方案需要手动操作localStorage/sessionStorage的API,而VueUse提供响应式的解决方案,让我们看看如何用更优雅的方式实现需求。
2. 环境搭建与基础配置
使用Vite创建Vue3项目:
npm create vite@latest my-vueus-ssr -- --template vue-ts
安装核心依赖:
npm install @vueuse/core
在组件中按需引入:
import { useLocalStorage, useSessionStorage } from '@vueuse/core'
3. useLocalStorage实战教学
3.1 主题切换记忆功能
<script setup lang="ts">
import { useLocalStorage } from '@vueuse/core'
// 类型安全的主题配置
type Theme = 'light' | 'dark' | 'system'
// 响应式主题状态,自动同步到localStorage
const theme = useLocalStorage<Theme>('theme-preference', 'system')
// 切换主题方法
const toggleTheme = () => {
theme.value = theme.value === 'dark' ? 'light' : 'dark'
document.documentElement.classList.toggle('dark')
}
</script>
<template>
<button @click="toggleTheme">
当前主题:{{ theme }}(点击切换)
</button>
</template>
功能亮点:
- 类型校验保障值安全
- 状态变更自动写入存储
- 支持复杂类型序列化
3.2 表单草稿自动保存
<script setup lang="ts">
import { useLocalStorage } from '@vueuse/core'
// 定义复杂的表单数据类型
interface DraftForm {
title: string
content: string
attachments: string[]
lastSaved?: Date
}
// 初始化带时间戳的表单草稿
const formDraft = useLocalStorage<DraftForm>('editor-draft', {
title: '',
content: '',
attachments: [],
lastSaved: new Date()
})
// 自动保存逻辑(示例使用防抖)
const autoSave = useDebounceFn(() => {
formDraft.value.lastSaved = new Date()
}, 1000)
</script>
<template>
<input v-model="formDraft.title" @input="autoSave" />
<textarea v-model="formDraft.content" @input="autoSave" />
<p>最后保存时间:{{ formDraft.lastSaved?.toLocaleString() }}</p>
</template>
4. useSessionStorage应用解析
4.1 购物车临时存储
<script setup lang="ts">
import { useSessionStorage } from '@vueuse/core'
type CartItem = {
id: string
name: string
price: number
quantity: number
}
// 初始化购物车数据结构
const shoppingCart = useSessionStorage<CartItem[]>('session-cart', [])
// 添加商品方法
const addToCart = (item: Omit<CartItem, 'quantity'>) => {
const existItem = shoppingCart.value.find(i => i.id === item.id)
existItem ? existItem.quantity++ : shoppingCart.value.push({ ...item, quantity: 1 })
}
</script>
安全特性:
- 标签页隔离保障数据独立
- 关闭浏览器自动清除数据
- 同源跨页面同步机制
4.2 多步骤表单状态保持
<script setup lang="ts">
import { useSessionStorage } from '@vueuse/core'
// 定义多步骤表单结构
interface MultiStepFormState {
currentStep: number
personalInfo: {
name: string
email: string
}
paymentInfo: {
cardNumber: string
expiry: string
}
}
// 初始化会话存储
const formState = useSessionStorage<MultiStepFormState>('multi-step-form', {
currentStep: 1,
personalInfo: { name: '', email: '' },
paymentInfo: { cardNumber: '', expiry: '' }
})
// 导航方法
const goToStep = (step: number) => {
formState.value.currentStep = Math.max(1, Math.min(step, 3))
}
</script>
5. 存储方案对比指南
特性 | localStorage | sessionStorage |
---|---|---|
生命周期 | 永久存储 | 会话级存储 |
作用域 | 同源跨标签页 | 单个标签页 |
容量限制 | 通常5MB | 通常5MB |
数据共享 | 所有同源窗口 | 仅当前窗口 |
适用场景 | 长期偏好设置 | 临时会话数据 |
6. 技术实现深度剖析
6.1 核心优势
- 响应式同步:数据变更自动更新DOM与存储
- 类型安全:完善的TypeScript支持
- 序列化智能处理:自动处理JSON转换
- 存储事件监听:支持跨窗口更新同步
6.2 潜在局限
- SSR限制:需配合useSSR插件使用
- 大文件存储:超过5MB会抛出错误
- 敏感数据风险:需自行加密处理
- 同步延迟:批量操作可能产生性能问题
7. 专家级实践建议
- 数据加密:敏感信息必须加密存储
import CryptoJS from 'crypto-js'
const encryptedStorage = useLocalStorage('secret', {
get: () => decrypt(localStorage.getItem('key')),
set: (value) => localStorage.setItem('key', encrypt(value))
})
- 容量监控:添加存储溢出处理
try {
useLocalStorage('big-data', hugeArray)
} catch (error) {
console.error('存储失败:', error)
showUserNotification('存储空间不足')
}
- 数据迁移:版本控制方案
const STORAGE_VERSION = '2.0'
const legacyData = localStorage.getItem('old-key')
if (legacyData) {
useLocalStorage('new-key').value = migrateData(legacyData)
}
8. 应用场景全景展望
- 用户偏好:主题、语言、字体大小
- 数据缓存:接口返回的频繁读取数据
- 工作恢复:文档编辑器自动保存
- 状态持久化:SPA应用的页面状态保持
- 离线功能:配合Service Worker实现
9. 总结与展望
VueUse的存储方案极大提升了开发效率,但需注意数据安全性问题。未来可探索:
- 与IndexedDB结合处理大文件
- 服务端渲染的深度适配
- 存储压缩算法的集成优化