Vue element admin 浏览器本地存储 localStorage、useStorage

发布时间:2026/7/28 21:42:24
Vue element admin 浏览器本地存储 localStorage、useStorage Vue Element Admin 浏览器本地存储从 localStorage 到 useStorage 的优雅之路一、为什么需要本地存储在开发后台管理系统时我们经常会遇到这样的场景用户登录后页面刷新一下用户信息就丢了又得重新登录。或者用户设置了一些偏好比如表格的列宽、主题颜色刷新一下就回到默认状态了。这是因为 Vue 是单页应用SPA数据默认存储在内存中刷新页面后内存被清空。为了解决这个问题我们需要把数据持久化到浏览器的本地存储中。## 二、传统 localStorage 的使用### 2.1 什么是 localStoragelocalStorage 是浏览器提供的一种本地存储机制可以存储字符串类型的数据容量一般在 5MB 左右数据不会因为页面刷新而丢失除非用户手动清除或者通过代码删除。### 2.2 基本使用方式javascript// 存储数据localStorage.setItem(userInfo, JSON.stringify({ name: 张三, age: 25, role: admin}));// 读取数据const userInfo JSON.parse(localStorage.getItem(userInfo));console.log(userInfo); // {name: 张三, age: 25, role: admin}// 删除数据localStorage.removeItem(userInfo);// 清空所有数据localStorage.clear();### 2.3 在 Vue Element Admin 中的传统实现在 Vue Element Admin 框架中我们通常会在src/utils/auth.js中封装 localStorage 的操作javascript// src/utils/auth.jsconst TokenKey Admin-Tokenexport function getToken() { return localStorage.getItem(TokenKey)}export function setToken(token) { return localStorage.setItem(TokenKey, token)}export function removeToken() { return localStorage.removeItem(TokenKey)}然后在 Vuex 中使用这些方法javascript// store/modules/user.jsimport { getToken, setToken, removeToken } from /utils/authconst state { token: getToken(), // 从 localStorage 初始化 userInfo: null}const mutations { SET_TOKEN: (state, token) { state.token token setToken(token) // 同步到 localStorage }, REMOVE_TOKEN: (state) { state.token removeToken() // 从 localStorage 删除 }}### 2.4 传统方式的痛点1.手动序列化/反序列化每次都要写JSON.stringify和JSON.parse2.数据不同步修改了 localStorage 不会自动更新组件3.类型丢失存储的数字、布尔值都会变成字符串4.代码冗余每个数据项都要写 get、set、remove 三个方法## 三、useStorageVue 3 组合式 API 的优雅方案### 3.1 什么是 useStorageuseStorage是 VueUse 库提供的一个组合式 API它把 localStorage 的操作封装成了响应式的 ref 对象实现了数据的双向绑定。### 3.2 安装 VueUsebashnpm install vueuse/core### 3.3 基本使用javascriptimport { useStorage } from vueuse/core// 存储字符串const token useStorage(admin-token, default-token)// 存储对象const userInfo useStorage(user-info, { name: , age: 0})// 存储数组const permissions useStorage(user-permissions, [])### 3.4 在 Vue Element Admin 中的应用让我们看看如何在 Vue Element Admin 中优雅地使用useStoragejavascript// store/modules/user.jsimport { defineStore } from piniaimport { useStorage } from vueuse/coreexport const useUserStore defineStore(user, { state: () ({ // 使用 useStorage 实现响应式本地存储 token: useStorage(admin-token, ), userInfo: useStorage(user-info, { id: null, name: , avatar: , roles: [] }), // 登录时间戳用于判断 token 是否过期 loginTime: useStorage(login-time, 0) }), getters: { // 判断是否登录 isLoggedIn: (state) !!state.token, // 获取用户角色 userRoles: (state) state.userInfo.roles, // 判断 token 是否过期假设 7 天过期 isTokenExpired: (state) { const now Date.now() const sevenDays 7 * 24 * 60 * 60 * 1000 return (now - state.loginTime) sevenDays } }, actions: { // 登录成功后保存用户信息 loginSuccess(data) { this.token data.token this.userInfo { id: data.id, name: data.name, avatar: data.avatar, roles: data.roles } this.loginTime Date.now() }, // 登出 logout() { this.token this.userInfo { id: null, name: , avatar: , roles: [] } this.loginTime 0 // 注意useStorage 会自动同步到 localStorage无需手动调用 } }})### 3.5 完整的实战示例下面是一个完整的用户设置页面的例子展示了 useStorage 的强大之处vuetemplate div classuser-settings el-card template #header span用户设置/span /template el-form :modelsettings label-width100px !-- 主题设置 -- el-form-item label主题颜色 el-color-picker v-modelsettings.themeColor / span classhint当前颜色{{ settings.themeColor }}/span /el-form-item !-- 语言设置 -- el-form-item label显示语言 el-select v-modelsettings.language el-option label中文 valuezh / el-option labelEnglish valueen / /el-select /el-form-item !-- 表格设置 -- el-form-item label每页条数 el-input-number v-modelsettings.pageSize :min10 :max100 :step10 / /el-form-item !-- 通知设置 -- el-form-item label消息通知 el-switch v-modelsettings.notificationEnabled / /el-form-item !-- 操作按钮 -- el-form-item el-button typeprimary clicksaveSettings保存设置/el-button el-button clickresetSettings重置默认/el-button el-button clickshowSettings查看当前设置/el-button /el-form-item /el-form /el-card /div/templatescript setupimport { useStorage } from vueuse/coreimport { ElMessage } from element-plus// 使用 useStorage 创建响应式设置对象// 所有修改都会自动同步到 localStorageconst settings useStorage(user-settings, { themeColor: #409EFF, // 默认主题色 language: zh, // 默认语言 pageSize: 20, // 默认每页条数 notificationEnabled: true, // 默认开启通知 sidebarCollapsed: false, // 侧边栏状态 lastLoginTime: null // 上次登录时间})// 保存设置function saveSettings() { // useStorage 自动同步无需手动操作 localStorage ElMessage.success(设置已保存自动同步到 localStorage) // 打印当前 localStorage 中的值 console.log(localStorage 中的值, JSON.parse(localStorage.getItem(user-settings)) )}// 重置为默认值function resetSettings() { settings.value { themeColor: #409EFF, language: zh, pageSize: 20, notificationEnabled: true, sidebarCollapsed: false, lastLoginTime: null } ElMessage.success(已重置为默认设置)}// 查看当前设置function showSettings() { ElMessage.info(当前设置主题色 ${settings.themeColor}语言 ${settings.language}每页 ${settings.pageSize} 条)}// 监听设置变化watch(settings, (newVal) { console.log(设置已更新同步到 localStorage)}, { deep: true })/scriptstyle scoped.hint { margin-left: 10px; font-size: 12px; color: #909399;}/style## 四、useStorage 的高级特性### 4.1 自定义序列化有些时候我们需要存储 Date 对象或其他特殊类型可以通过自定义序列化器来实现javascriptimport { useStorage } from vueuse/core// 自定义序列化器const customSerializer { read: (v) JSON.parse(v, (key, value) { // 自动转换日期字符串为 Date 对象 if (typeof value string /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) { return new Date(value) } return value }), write: (v) JSON.stringify(v)}// 使用自定义序列化器const dateSettings useStorage(date-settings, { lastVisit: new Date(), reminders: []}, localStorage, { serializer: customSerializer })### 4.2 监听 localStorage 变化当其他标签页修改了 localStorage 时useStorage 可以自动感知javascriptimport { useStorage, useEventListener } from vueuse/coreconst token useStorage(admin-token, )// 监听 storage 事件其他标签页修改时触发useEventListener(window, storage, (event) { if (event.key admin-token) { console.log(其他标签页修改了 token) // token 的值会自动更新 }})## 五、性能优化建议1.合理设置默认值避免频繁修改导致大量写入2.使用 debounce对于频繁变化的值如搜索历史可以使用防抖3.定期清理对于过期的数据定期清理javascriptimport { useStorage, useDebounceFn } from vueuse/core// 搜索历史const searchHistory useStorage(search-history, [])// 使用防抖避免频繁写入const addSearch useDebounceFn((keyword) { if (keyword !searchHistory.value.includes(keyword)) { searchHistory.value.unshift(keyword) // 只保留最近 20 条 if (searchHistory.value.length 20) { searchHistory.value searchHistory.value.slice(0, 20) } }}, 500)## 总结从传统的 localStorage 操作到 VueUse 的 useStorage我们经历了从繁琐到优雅的转变。useStorage 不仅解决了手动序列化、数据同步等问题还提供了响应式、类型安全、自定义序列化等高级特性。在 Vue Element Admin 项目中合理使用 useStorage 可以1.减少样板代码不再需要手动 get/set/remove2.保持数据同步响应式绑定修改即存储3.类型安全自动处理 JSON 序列化4.跨标签页同步自动监听 storage 事件建议在项目中使用 useStorage 替代传统的 localStorage 操作让数据持久化变得简单而优雅。记住好的工具不仅解决问题更能提升开发体验。