所有前端必看!LocalStorage看似简单,却有90%的人用错------存对象报错、存数组失效、数据污染、内存溢出,甚至导致页面卡顿。全程实操干货+通用封装,Vue/React/Uniapp/小程序/Node都能用,复制就能避免所有坑
先搞懂:LocalStorage核心痛点,你一定踩过
做前端开发,谁没用 LocalStorage 存过 token、用户信息?但大多数人都是裸写 localStorage.setItem、localStorage.getItem,看似简单,实则全是坑:
- 只能存字符串 :存对象/数组直接报错,或取出来变成
[object Object]; - 没有过期时间:存的 token、临时数据一直占用内存,导致数据污染;
- 没有容错处理:取不到数据直接报错,影响页面渲染;
- 键名混乱:多个页面/组件存数据,容易覆盖、冲突。
重点:LocalStorage 是前端本地存储的基础,Vue、React、Uniapp、小程序、Node(前端渲染)都能用。一套通用封装,彻底解决所有痛点,不用重复写冗余代码。
核心干货:LocalStorage通用封装(直接复制,多框架通用)
新建 utils/storage.js,一次封装,全局使用。支持存字符串、对象、数组,带过期时间、容错处理、键名统一,复制到任何前端项目都能直接用!
javascript
/**
* LocalStorage通用封装(Vue/React/Uniapp/小程序通用)
* 支持:存字符串、对象、数组 + 过期时间 + 容错处理 + 键名统一
*/
const STORAGE_KEY_PREFIX = 'frontend_'; // 键名前缀,避免冲突
// 1. 存数据(支持过期时间,单位:秒)
export const setStorage = (key, value, expire = 0) => {
try {
// 处理对象/数组,转为JSON字符串(LocalStorage只能存字符串)
const data = {
value: typeof value === 'object' ? JSON.stringify(value) : value,
expire: expire > 0 ? Date.now() + expire * 1000 : 0 // 0表示永久有效
};
// 键名加前缀,避免和其他项目/插件冲突
localStorage.setItem(`${STORAGE_KEY_PREFIX}${key}`, JSON.stringify(data));
} catch (error) {
console.error('LocalStorage存储失败:', error);
// 兼容低版本浏览器/隐私模式(LocalStorage不可用)
alert('浏览器存储不可用,请开启正常模式后重试');
}
};
// 2. 取数据(自动处理JSON解析,判断过期)
export const getStorage = (key) => {
try {
const storageKey = `${STORAGE_KEY_PREFIX}${key}`;
const dataStr = localStorage.getItem(storageKey);
if (!dataStr) return null;
const data = JSON.parse(dataStr);
// 判断是否过期(expire=0表示永久有效)
if (data.expire > 0 && Date.now() > data.expire) {
// 过期后自动删除,避免无效数据占用内存
localStorage.removeItem(storageKey);
return null;
}
// 自动解析JSON(如果存的是对象/数组)
try {
return JSON.parse(data.value);
} catch (e) {
// 不是JSON格式,直接返回原始值(字符串)
return data.value;
}
} catch (error) {
console.error('LocalStorage获取失败:', error);
return null;
}
};
// 3. 删除单个数据
export const removeStorage = (key) => {
try {
localStorage.removeItem(`${STORAGE_KEY_PREFIX}${key}`);
} catch (error) {
console.error('LocalStorage删除失败:', error);
}
};
// 4. 清空所有数据(只清空当前项目的,不影响其他项目)
export const clearStorage = () => {
try {
// 只删除带前缀的键,避免清空其他项目的存储
Object.keys(localStorage).forEach(key => {
if (key.startsWith(STORAGE_KEY_PREFIX)) {
localStorage.removeItem(key);
}
});
} catch (error) {
console.error('LocalStorage清空失败:', error);
}
};
// 5. 批量存数据
export const setStorageBatch = (obj, expire = 0) => {
try {
Object.entries(obj).forEach(([key, value]) => {
setStorage(key, value, expire);
});
} catch (error) {
console.error('LocalStorage批量存储失败:', error);
}
};
实战用法:多框架示例,直接复制
不管是 Vue、React、Uniapp,用法完全一致,只需引入封装好的方法,无需额外适配。以下示例覆盖 80% 的使用场景。
1. 基础用法:存/取字符串、对象、数组
javascript
// 引入封装的方法(所有框架通用)
import { setStorage, getStorage, removeStorage } from '@/utils/storage';
// 1. 存字符串(比如token)
setStorage('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', 86400); // 过期时间1天(86400秒)
// 2. 存对象(比如用户信息)
const userInfo = { id: 1, name: '张三', age: 25 };
setStorage('userInfo', userInfo, 86400);
// 3. 存数组(比如历史记录)
const historyList = ['Vue', 'React', 'JS'];
setStorage('historyList', historyList); // 不设过期时间,永久有效
// 4. 取数据(自动解析对象/数组,无需手动JSON.parse)
const token = getStorage('token');
const user = getStorage('userInfo'); // 直接拿到对象,无需解析
const history = getStorage('historyList'); // 直接拿到数组
// 5. 删除数据
removeStorage('token'); // 删除单个
// clearStorage(); // 清空当前项目所有存储
2. Vue3/Uniapp页面中使用
js
<script setup>
import { ref, onMounted } from 'vue';
import { setStorage, getStorage } from '@/utils/storage';
const userInfo = ref({});
// 页面加载时,从LocalStorage取用户信息
onMounted(() => {
const user = getStorage('userInfo');
if (user) {
userInfo.value = user;
}
});
// 登录成功后,存用户信息和token
const login = async () => {
const res = await loginApi(); // 登录接口
setStorage('token', res.data.token, 86400);
setStorage('userInfo', res.data.user, 86400);
userInfo.value = res.data.user;
};
</script>
3. React页面中使用
jsx
import { useState, useEffect } from 'react';
import { setStorage, getStorage, removeStorage } from '@/utils/storage';
function UserPage() {
const [user, setUser] = useState({});
useEffect(() => {
// 组件挂载时取数据
const userInfo = getStorage('userInfo');
if (userInfo) {
setUser(userInfo);
}
}, []);
// 退出登录,删除存储
const logout = () => {
removeStorage('token');
removeStorage('userInfo');
setUser({});
};
return (
<div>
{user.name}
<button onClick={logout}>退出登录</button>
</div>
);
}
4. 小程序/Uniapp适配(特殊处理)
小程序不支持 window.localStorage,需替换为 wx.setStorageSync 等原生 API,修改封装方法即可,核心逻辑不变:
javascript
// 小程序版本封装(utils/storage.js)
const STORAGE_KEY_PREFIX = 'frontend_';
// 存数据
export const setStorage = (key, value, expire = 0) => {
try {
const data = {
value: typeof value === 'object' ? JSON.stringify(value) : value,
expire: expire > 0 ? Date.now() + expire * 1000 : 0
};
wx.setStorageSync(`${STORAGE_KEY_PREFIX}${key}`, data);
} catch (error) {
console.error('存储失败:', error);
wx.showToast({ title: '存储不可用', icon: 'none' });
}
};
// 取数据(其他方法同理,替换为wx.getStorageSync、wx.removeStorageSync)
export const getStorage = (key) => {
try {
const storageKey = `${STORAGE_KEY_PREFIX}${key}`;
const data = wx.getStorageSync(storageKey);
if (!data) return null;
if (data.expire > 0 && Date.now() > data.expire) {
wx.removeStorageSync(storageKey);
return null;
}
try {
return JSON.parse(data.value);
} catch (e) {
return data.value;
}
} catch (error) {
console.error('获取失败:', error);
return null;
}
};
实战避坑:5个高频坑,新手必避
坑1:直接存对象/数组,导致报错或解析失败
错误示例 :localStorage.setItem('user', {name: '张三'}),直接存对象会报错。
正确做法 :用封装的 setStorage,自动将对象/数组转为 JSON 字符串,取的时候自动解析。
坑2:不设过期时间,导致数据污染
存 token、临时数据时,不设过期时间,用户退出后数据依然存在,再次登录会出现异常。
正确做法:给敏感数据、临时数据设置过期时间(比如 token 设 1 天)。
坑3:键名不统一,导致覆盖冲突
多个组件/页面存数据,键名都是 "user""data",容易互相覆盖。
正确做法 :用前缀统一键名(封装中已自带 frontend_ 前缀),避免冲突。
坑4:忽略浏览器兼容性,导致报错
部分低版本浏览器、隐私模式下,LocalStorage 不可用,裸写会报错。
正确做法:封装中添加容错处理,捕获异常并提示用户。
坑5:清空所有存储,影响其他项目
错误示例 :直接用 localStorage.clear(),会清空浏览器中所有项目的 LocalStorage。
正确做法 :用封装的 clearStorage,只清空当前项目带前缀的存储。
进阶技巧:LocalStorage进阶用法
1. 监听 LocalStorage 变化(跨页面通信)
javascript
// 页面A监听存储变化
window.addEventListener('storage', (e) => {
// 只监听当前项目的存储变化(带前缀)
if (e.key?.startsWith(STORAGE_KEY_PREFIX)) {
console.log('存储变化:', e.key, e.newValue);
// 比如监听token变化,实现跨页面登录状态同步
if (e.key === `${STORAGE_KEY_PREFIX}token`) {
// 处理登录状态更新
}
}
});
// 页面B修改存储,页面A会触发监听
setStorage('token', 'newToken');
2. 限制存储大小,避免内存溢出
LocalStorage 默认存储上限约 5MB,存大量数据会导致内存溢出。可在封装中添加存储大小校验:
javascript
// 新增:校验存储大小
const checkStorageSize = (value) => {
const valueStr = typeof value === 'object' ? JSON.stringify(value) : value;
const size = new Blob([valueStr]).size;
// 限制单条数据不超过1MB
if (size > 1 * 1024 * 1024) {
alert('存储数据过大,建议拆分存储');
return false;
}
return true;
};
// 在setStorage中添加校验
export const setStorage = (key, value, expire = 0) => {
if (!checkStorageSize(value)) return;
// 原有逻辑...
};
结尾:干货总结
LocalStorage 是前端必备的本地存储工具。一套通用封装,解决存对象、过期时间、冲突、容错等所有痛点,适配所有前端框架,复制就能用,避开 5 个高频坑,再也不用为存储问题头疼。
各位互联网搭子,要是这篇文章成功引起了你的注意,别犹豫,关注、点赞、评论、分享走一波,让我们把这份默契延续下去,一起在知识的海洋里乘风破浪!