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

发布时间:2026/11/6 1:23:58

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 操作让数据持久化变得简单而优雅。记住好的工具不仅解决问题更能提升开发体验。
延伸阅读

更多相关文章

2026/11/6 1:23:56

YOLOv8模型部署全链路优化:从1.2FPS到35FPS的实战指南

大家好,我是专注于计算机视觉与深度学习部署的开发者。在实际项目中,我们常常遇到这样的困境:一个训练好的 YOLOv8 模型,在推理时帧率(FPS)低得令人沮丧,例如只有 1.2FPS,这完全无法…

2026/11/4 8:39:34

联辉科 LTK5112 28W单声道F类音频功率放大器 ESOP-8 技术解析

在蓝牙音箱、智能音箱、导航仪、便携游戏机、拉杆音箱等需要高功率输出的音频产品中,需要一款既能提供足够输出功率、又能灵活切换工作模式以适应不同应用场景(如FM收音时需AB类模式避免EMI干扰)的音频功率放大器。LTK5112是一款4Ω负载下可提…

2026/11/3 14:30:52

CKEDITOR处理Word图文混排的挑战与解决方案

1. 互联网平台中CKEDITOR处理Word图文混排的核心挑战在内容管理系统和在线文档编辑场景中,CKEDITOR作为老牌富文本编辑器,处理Word文档导入时总会遇到"水土不服"的情况。最近在开发教育行业的在线题库系统时,我们需要处理大量包含公…

2026/11/6 1:23:45

前端入职第一天环境配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/6 1:23:45

Weylus:3 步把平板变成电脑绘图板,压感多触全都有

Weylus:3 步把平板变成电脑绘图板,压感多触全都有 【免费下载链接】Weylus Use your tablet as graphic tablet/touch screen on your computer. 项目地址: https://gitcode.com/gh_mirrors/we/Weylus 家里有闲置的平板,却只是吃灰&am…

2026/11/6 1:23:45

Jellyfin 字幕配置:从自动下载到多语言切换的完整路径

Jellyfin 字幕配置:从自动下载到多语言切换的完整路径 【免费下载链接】jellyfin The Free Software Media System - Server Backend & API 项目地址: https://gitcode.com/GitHub_Trending/je/jellyfin 一部电影播到一半,字幕全部变成方框&a…

2026/11/6 1:18:44

CAPWAP隧道基本概念:集中转发和本地转发

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/6 1:03:39

MCU晶振电路设计全解析:从负载电容计算到PCB布局调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑