纣捎牟 发表于 2025-8-25 13:15:28

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

目录

[*]localStorage 与 useStorage 的区别

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

[*]删除 userInfo 的 key 方法

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


在你的代码中,userInfo 的浏览器本地存储是在 defineStore("user", () => { ... }) 函数内部的第一行实现的:
auth.ts
// 访问 token 缓存的 key
const ACCESS_TOKEN_KEY = "access_token";
// 刷新 token 缓存的 key
const REFRESH_TOKEN_KEY = "refresh_token";

function getAccessToken(): string {
return localStorage.getItem(ACCESS_TOKEN_KEY) || "";
}

function setAccessToken(token: string) {
localStorage.setItem(ACCESS_TOKEN_KEY, token);
}

function getRefreshToken(): string {
return localStorage.getItem(REFRESH_TOKEN_KEY) || "";
}

function setRefreshToken(token: string) {
localStorage.setItem(REFRESH_TOKEN_KEY, token);
}

function clearToken() {
localStorage.removeItem(ACCESS_TOKEN_KEY);
localStorage.removeItem(REFRESH_TOKEN_KEY);
}

export { getAccessToken, setAccessToken, clearToken, getRefreshToken, setRefreshToken };import { setAccessToken, setRefreshToken, getRefreshToken, clearToken } from "@/utils/auth";

export const useUserStore = defineStore("user", () => {
const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);
const roleList = useStorage<RoleInfo[]>("roleList", []);


/**
   * 登录
   *
   * @param {LoginFormData}
   * @returns
   */
function login(LoginFormData: LoginFormData) {
    return new Promise<void>((resolve, reject) => {
      console.log("modules.user.login");
      AuthAPI.login(LoginFormData)
      .then((data) => {
          const { accessToken, user } = data;
          setAccessToken(accessToken);
          if (User.RoleList && Array.isArray(user.RoleList)) {
            roleList.value = user.RoleList;
          } else {
            roleList.value = []; // 确保总是数组
            console.warn("RoleList is not an array or is undefined");
          }
          resolve();
      })
      .catch((error) => {
          reject(error);
      });
    });
}

    /**
   * 获取用户信息
   *
   * @returns {UserInfo} 用户信息
   */
function getUserInfo() {
    return new Promise<UserInfo>((resolve, reject) => {
      UserAPI.getInfo()
      .then((data) => {
          if (!data) {
            reject("Verification failed, please Login again.");
            return;
          }
          Object.assign(userInfo.value, { ...data });
          resolve(data);
      })
      .catch((error) => {
          reject(error);
      });
    });
}这行代码是关键,
const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);它使用了 useStorage 函数(通常来自 @vueuse/core 或类似的工具库)来创建一个响应式的引用,该引用会自动将数据持久化到浏览器的本地存储中。
具体分析:

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

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

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

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

localStorage(原生 API)

直接操作本地存储的原生浏览器 API:
// 存储数据
localStorage.setItem('userInfo', JSON.stringify(userData));

// 读取数据
const data = JSON.parse(localStorage.getItem('userInfo') || '{}');

// 删除数据
localStorage.removeItem('userInfo');

// 清空所有
localStorage.clear();特点:

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

基于 localStorage 封装的响应式工具函数:
import { useStorage } from '@vueuse/core';

// 自动处理序列化和响应式
const userInfo = useStorage('userInfo', {} as UserInfo);

// 直接赋值,自动保存到 localStorage
userInfo.value = newData;

// 读取数据,直接使用即可
console.log(userInfo.value);特点:

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

使用 localStorage:
// 需要手动处理
const user = ref(JSON.parse(localStorage.getItem('userInfo') || '{}'));

function updateUser(newData) {
user.value = newData;
localStorage.setItem('userInfo', JSON.stringify(newData)); // 手动保存
}使用 useStorage:
// 自动处理一切
const user = useStorage('userInfo', {});

function updateUser(newData) {
user.value = newData; // 自动保存到 localStorage
}总结

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

1. 使用 useStorage 的推荐方式

如果你使用的是 @vueuse/core 的 useStorage:
import { useStorage } from '@vueuse/core';

// 清除数据并移除 key
function clearUserData() {
return new Promise<void>((resolve) => {
    clearToken();
    usePermissionStoreHook().resetRouter();
    useDictStoreHook().clearDictionaryCache();
    //清除数据,key 还在
    userInfo.value = {} as UserInfo;
    // 推荐方式:直接设置为 null 或 undefined,useStorage 会自动移除 key
    userInfo.value = null as any;
    // 或者
    // userInfo.value = undefined as any;
   
    resolve();
});
}2. 手动删除 localStorage 的 key

function clearUserData() {
return new Promise<void>((resolve) => {
    clearToken();
    usePermissionStoreHook().resetRouter();
    useDictStoreHook().clearDictionaryCache();
   
    // 方式1:直接操作 localStorage
    localStorage.removeItem('userInfo');
   
    // 方式2:如果还想保持响应式,需要重新赋值
    userInfo.value = {} as UserInfo;
   
    resolve();
});
}3. 完整的清除方案

/**
* 清理用户数据(完全清除)
*/
function clearUserDataCompletely() {
return new Promise<void>((resolve) => {
    clearToken();
    usePermissionStoreHook().resetRouter();
    useDictStoreHook().clearDictionaryCache();
   
    // 方案A:使用 localStorage.removeItem(推荐)
    localStorage.removeItem('userInfo');
    userInfo.value = {} as UserInfo; // 保持响应式一致性
   
    // 方案B:设置为 null/undefined(useStorage 会自动处理)
    // userInfo.value = null as any;
   
    resolve();
});
}4. 验证 key 是否被删除

// 检查 key 是否存在的方法
function isUserInfoKeyExists(): boolean {
return localStorage.getItem('userInfo') !== null;
}

// 使用示例
console.log('userInfo key exists:', isUserInfoKeyExists()); // false推荐方案

在你的 clearUserData 函数中这样实现:
function clearUserData() {
return new Promise<void>((resolve) => {
    clearToken();
    usePermissionStoreHook().resetRouter();
    useDictStoreHook().clearDictionaryCache();
   
    // 同时操作 localStorage 和响应式变量
    localStorage.removeItem('userInfo'); // 删除 key
    userInfo.value = {} as UserInfo;   // 重置响应式变量
   
    resolve();
});
}这样就能确保:

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

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除
页: [1]
查看完整版本: Vue element admin 浏览器本地存储 localStorage、useStorage