找回密码
 立即注册
首页 业界区 业界 Vue element admin 浏览器本地存储 localStorage、useS ...

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

纣捎牟 7 天前
目录

  • localStorage 与 useStorage 的区别

    • localStorage(原生 API)
    • useStorage(VueUse 工具函数)
    • 对比示例
    • 总结

  • 删除 userInfo 的 key 方法

    • 1. 使用 useStorage 的推荐方式
    • 2. 手动删除 localStorage 的 key
    • 3. 完整的清除方案
    • 4. 验证 key 是否被删除
    • 推荐方案


在你的代码中,userInfo 的浏览器本地存储是在 defineStore("user", () => { ... }) 函数内部的第一行实现的
auth.ts
  1. // 访问 token 缓存的 key
  2. const ACCESS_TOKEN_KEY = "access_token";
  3. // 刷新 token 缓存的 key
  4. const REFRESH_TOKEN_KEY = "refresh_token";
  5. function getAccessToken(): string {
  6.   return localStorage.getItem(ACCESS_TOKEN_KEY) || "";
  7. }
  8. function setAccessToken(token: string) {
  9.   localStorage.setItem(ACCESS_TOKEN_KEY, token);
  10. }
  11. function getRefreshToken(): string {
  12.   return localStorage.getItem(REFRESH_TOKEN_KEY) || "";
  13. }
  14. function setRefreshToken(token: string) {
  15.   localStorage.setItem(REFRESH_TOKEN_KEY, token);
  16. }
  17. function clearToken() {
  18.   localStorage.removeItem(ACCESS_TOKEN_KEY);
  19.   localStorage.removeItem(REFRESH_TOKEN_KEY);
  20. }
  21. export { getAccessToken, setAccessToken, clearToken, getRefreshToken, setRefreshToken };
复制代码
  1. import { setAccessToken, setRefreshToken, getRefreshToken, clearToken } from "@/utils/auth";
  2. export const useUserStore = defineStore("user", () => {
  3.   const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);
  4.   const roleList = useStorage<RoleInfo[]>("roleList", []);
  5.   
  6.   
  7.   /**
  8.    * 登录
  9.    *
  10.    * @param {LoginFormData}
  11.    * @returns
  12.    */
  13.   function login(LoginFormData: LoginFormData) {
  14.     return new Promise<void>((resolve, reject) => {
  15.       console.log("modules.user.login");
  16.       AuthAPI.login(LoginFormData)
  17.         .then((data) => {
  18.           const { accessToken, user } = data;
  19.           setAccessToken(accessToken);
  20.           if (User.RoleList && Array.isArray(user.RoleList)) {
  21.             roleList.value = user.RoleList;
  22.           } else {
  23.             roleList.value = []; // 确保总是数组
  24.             console.warn("RoleList is not an array or is undefined");
  25.           }
  26.           resolve();
  27.         })
  28.         .catch((error) => {
  29.           reject(error);
  30.         });
  31.     });
  32.   }
  33.   
  34.     /**
  35.    * 获取用户信息
  36.    *
  37.    * @returns {UserInfo} 用户信息
  38.    */
  39.   function getUserInfo() {
  40.     return new Promise<UserInfo>((resolve, reject) => {
  41.       UserAPI.getInfo()
  42.         .then((data) => {
  43.           if (!data) {
  44.             reject("Verification failed, please Login again.");
  45.             return;
  46.           }
  47.           Object.assign(userInfo.value, { ...data });
  48.           resolve(data);
  49.         })
  50.         .catch((error) => {
  51.           reject(error);
  52.         });
  53.     });
  54.   }
复制代码
这行代码是关键,
  1. const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);
复制代码
它使用了 useStorage 函数(通常来自 @vueuse/core 或类似的工具库)来创建一个响应式的引用,该引用会自动将数据持久化到浏览器的本地存储中。
具体分析:

  • 存储时机:当调用 getUserInfo() 方法时,通过这行代码:
    1. Object.assign(userInfo.value, { ...data });
    复制代码
    将获取到的用户数据赋值给 userInfo.value,此时 useStorage 会自动将这些数据保存到 localStorage。
  • 存储位置:数据会被存储在浏览器的 localStorage 中,键名为 "userInfo"。
  • 自动持久化:useStorage 会自动处理:

    • 初始时从 localStorage 读取数据
    • 数据变更时自动写入 localStorage
    • 页面刷新后数据仍然保持

验证方式
你可以在浏览器开发者工具中查看:

  • 打开「Application」标签页
  • 选择「Local Storage」
  • 查看你的网站域名下是否存在 userInfo 这个键,其值就是序列化的用户信息
注意:clearUserData() 函数中没有直接清除 userInfo,你可能需要在其中添加:
  1. userInfo.value = {} as UserInfo;     // 保持响应式一致性
  2. roleList.value = [] as RoleInfo[];   // 保持响应式一致性
复制代码
来确保用户登出时本地存储的用户信息也被清除。
localStorage 与 useStorage 的区别

localStorage(原生 API)

直接操作本地存储的原生浏览器 API
  1. // 存储数据
  2. localStorage.setItem('userInfo', JSON.stringify(userData));
  3. // 读取数据
  4. const data = JSON.parse(localStorage.getItem('userInfo') || '{}');
  5. // 删除数据
  6. localStorage.removeItem('userInfo');
  7. // 清空所有
  8. localStorage.clear();
复制代码
特点

  • ✅ 浏览器原生支持,无需额外依赖
  • ❌ 需要手动序列化/反序列化(JSON.stringify/JSON.parse)
  • ❌ 不是响应式的,数据变更不会自动更新界面
  • ❌ 需要手动处理存储和读取逻辑
useStorage(VueUse 工具函数)

基于 localStorage 封装的响应式工具函数
  1. import { useStorage } from '@vueuse/core';
  2. // 自动处理序列化和响应式
  3. const userInfo = useStorage('userInfo', {} as UserInfo);
  4. // 直接赋值,自动保存到 localStorage
  5. userInfo.value = newData;
  6. // 读取数据,直接使用即可
  7. console.log(userInfo.value);
复制代码
特点

  • ✅ 自动序列化/反序列化
  • ✅ 响应式,数据变更自动更新界面
  • ✅ 与 Vue 响应式系统无缝集成
  • ✅ 类型安全(TypeScript 支持)
  • ❌ 需要安装 @vueuse/core 依赖
对比示例

使用 localStorage
  1. // 需要手动处理
  2. const user = ref(JSON.parse(localStorage.getItem('userInfo') || '{}'));
  3. function updateUser(newData) {
  4.   user.value = newData;
  5.   localStorage.setItem('userInfo', JSON.stringify(newData)); // 手动保存
  6. }
复制代码
使用 useStorage
  1. // 自动处理一切
  2. const user = useStorage('userInfo', {});
  3. function updateUser(newData) {
  4.   user.value = newData; // 自动保存到 localStorage
  5. }
复制代码
总结

特性localStorageuseStorage响应式❌ 否✅ 是自动序列化❌ 需要手动✅ 自动Vue 集成❌ 需要封装✅ 无缝集成类型安全❌ 有限✅ 完整TS支持使用便捷性❌ 较低✅ 极高推荐使用 useStorage,特别是在 Vue 项目中,它能极大简化本地存储的操作并提供更好的开发体验。
删除 userInfo 的 key 方法

1. 使用 useStorage 的推荐方式

如果你使用的是 @vueuse/core 的 useStorage
  1. import { useStorage } from '@vueuse/core';
  2. // 清除数据并移除 key
  3. function clearUserData() {
  4.   return new Promise<void>((resolve) => {
  5.     clearToken();
  6.     usePermissionStoreHook().resetRouter();
  7.     useDictStoreHook().clearDictionaryCache();
  8.     //清除数据,key 还在
  9.     userInfo.value = {} as UserInfo;
  10.     // 推荐方式:直接设置为 null 或 undefined,useStorage 会自动移除 key
  11.     userInfo.value = null as any;
  12.     // 或者
  13.     // userInfo.value = undefined as any;
  14.    
  15.     resolve();
  16.   });
  17. }
复制代码
2. 手动删除 localStorage 的 key
  1. function clearUserData() {
  2.   return new Promise<void>((resolve) => {
  3.     clearToken();
  4.     usePermissionStoreHook().resetRouter();
  5.     useDictStoreHook().clearDictionaryCache();
  6.    
  7.     // 方式1:直接操作 localStorage
  8.     localStorage.removeItem('userInfo');
  9.    
  10.     // 方式2:如果还想保持响应式,需要重新赋值
  11.     userInfo.value = {} as UserInfo;
  12.    
  13.     resolve();
  14.   });
  15. }
复制代码
3. 完整的清除方案
  1. /**
  2. * 清理用户数据(完全清除)
  3. */
  4. function clearUserDataCompletely() {
  5.   return new Promise<void>((resolve) => {
  6.     clearToken();
  7.     usePermissionStoreHook().resetRouter();
  8.     useDictStoreHook().clearDictionaryCache();
  9.    
  10.     // 方案A:使用 localStorage.removeItem(推荐)
  11.     localStorage.removeItem('userInfo');
  12.     userInfo.value = {} as UserInfo; // 保持响应式一致性
  13.    
  14.     // 方案B:设置为 null/undefined(useStorage 会自动处理)
  15.     // userInfo.value = null as any;
  16.    
  17.     resolve();
  18.   });
  19. }
复制代码
4. 验证 key 是否被删除
  1. // 检查 key 是否存在的方法
  2. function isUserInfoKeyExists(): boolean {
  3.   return localStorage.getItem('userInfo') !== null;
  4. }
  5. // 使用示例
  6. console.log('userInfo key exists:', isUserInfoKeyExists()); // false
复制代码
推荐方案

在你的 clearUserData 函数中这样实现
  1. function clearUserData() {
  2.   return new Promise<void>((resolve) => {
  3.     clearToken();
  4.     usePermissionStoreHook().resetRouter();
  5.     useDictStoreHook().clearDictionaryCache();
  6.    
  7.     // 同时操作 localStorage 和响应式变量
  8.     localStorage.removeItem('userInfo'); // 删除 key
  9.     userInfo.value = {} as UserInfo;     // 重置响应式变量
  10.    
  11.     resolve();
  12.   });
  13. }
复制代码
这样就能确保:

  • ✅ localStorage 中的 userInfo key 被完全删除
  • ✅ 响应式变量保持一致性
  • ✅ 下次访问时不会读取到旧的缓存数据

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册