LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

前端必看!LocalStorage这么用,再也不踩坑(多框架通用,直接复制)

zhenglin
2026年4月9日 14:13 本文热度 47

所有前端必看!LocalStorage看似简单,却有90%的人用错——存对象报错、存数组失效、数据污染、内存溢出,甚至导致页面卡顿。全程实操干货+通用封装,Vue/React/Uniapp/小程序/Node都能用,复制就能避免所有坑

先搞懂:LocalStorage核心痛点,你一定踩过

做前端开发,谁没用 LocalStorage 存过 token、用户信息?但大多数人都是裸写 localStorage.setItemlocalStorage.getItem,看似简单,实则全是坑:

  • 只能存字符串:存对象/数组直接报错,或取出来变成 [object Object]

  • 没有过期时间:存的 token、临时数据一直占用内存,导致数据污染;

  • 没有容错处理:取不到数据直接报错,影响页面渲染;

  • 键名混乱:多个页面/组件存数据,容易覆盖、冲突。


重点:LocalStorage 是前端本地存储的基础,Vue、React、Uniapp、小程序、Node(前端渲染)都能用。一套通用封装,彻底解决所有痛点,不用重复写冗余代码。


核心干货:LocalStorage通用封装(直接复制,多框架通用)

新建 utils/storage.js,一次封装,全局使用。支持存字符串、对象、数组,带过期时间、容错处理、键名统一,复制到任何前端项目都能直接用!

/**

 * 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. 基础用法:存/取字符串、对象、数组

// 引入封装的方法(所有框架通用)

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页面中使用

<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页面中使用

代码高亮:

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,修改封装方法即可,核心逻辑不变:

// 小程序版本封装(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 变化(跨页面通信)

// 页面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,存大量数据会导致内存溢出。可在封装中添加存储大小校验:

// 新增:校验存储大小

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 个高频坑,再也不用为存储问题头疼。


阅读原文



该文章在 2026/4/9 14:13:00 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-2  粤公网安备44030602007207号