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

小程序到底用Store还是LocalStorage ?

freeflydom
2025年11月4日 8:48 本文热度 305

很多开发者刚开始都会觉得“既然localStorage能存公共数据,为啥还要store?”,但其实两者解决的是完全不同的问题:localStorage是“持久化存储工具”,而store是“内存状态管理工具”,看似都能存数据,实则在“实时同步”“效率”“状态关联”上差了关键一步,绝非“脱裤子放屁”。

一、先戳localStorage的3个“硬伤”——你用它管理实时状态会踩的坑

假设你把Token、isLogin存在localStorage里,想实现“登录后所有页面立刻更新登录按钮(显示‘退出’)”,会发现根本做不到或很麻烦:

1. 「改了数据,其他页面不会主动通知」——实时同步失效

localStorage是“被动存储”,它没有“发布订阅”能力:
比如A页面登录成功,存了Token到localStorage:

// A页面:登录成功
wx.setStorageSync('token', 'xxx123');
wx.setStorageSync('isLogin', true);

但B页面此时已经打开(比如Tab页),它不会知道localStorage变了,登录按钮还是显示“登录”,必须手动做以下操作之一:

  • 方案1:每次页面显示都读localStorage(冗余且不实时)
    B页面得在onShow里反复读:

    onShow() {
      const isLogin = wx.getStorageSync('isLogin');
      this.setData({ isLogin }); // 每次切到B页面才更新,不切就不更
    }
    

    如果B页面是个长列表页,频繁切页会反复读磁盘,影响性能。

  • 方案2:自己写监听逻辑(复杂且容易漏)
    得用小程序的wx.onStorageChange监听localStorage变化,但这玩意儿有坑:

    // B页面:监听localStorage变化
    onLoad() {
      this.storageListener = wx.onStorageChange((res) => {
        if (res.key === 'isLogin') {
          this.setData({ isLogin: res.newValue });
        }
      });
    }
    onUnload() {
      // 必须手动销毁监听,否则内存泄漏
      this.storageListener();
    }
    

    每个需要同步的页面都得写这段代码,3个页面就写3遍,还容易忘销毁监听。

store的核心优势就是“自动通知”:只要配置了storeWatch,A页面改了isLogin,B/C/D页面会立刻收到通知并更新,不用写任何监听代码——这正是你说的“一个地方改,其他地方立刻响应”。

2. 「读写效率低」——频繁操作会卡顿

localStorage是磁盘存储(存在手机本地文件里),而store管理的是内存数据(存在小程序的内存里)。
比如你做“切换账号”功能,需要同时更新:tokenuserInfoisLoginaudienceUserId4个状态:

  • 用localStorage:得写4次wx.setStorageSync(4次磁盘写入),读的时候得4次wx.getStorageSync(4次磁盘读取),磁盘操作比内存慢100倍以上,频繁操作会有卡顿感。
  • 用store:直接操作内存里的globalData,1次store.set就能更新关联状态,读写几乎无延迟——这对小程序的流畅度很重要。

3. 「只能存字符串」——复杂状态会出问题

localStorage只能存字符串,存对象/数字/布尔值都得手动JSON.stringifyJSON.parse,容易踩坑:

// 存用户信息(对象),必须转字符串
const userInfo = { name: '张三', age: 20 };
wx.setStorageSync('userInfo', JSON.stringify(userInfo));
// 取的时候转回来
const userInfo = JSON.parse(wx.getStorageSync('userInfo'));
// 坑1:如果数据里有函数/循环引用,JSON.stringify会报错
// 坑2:如果localStorage被清空,JSON.parse会报“Unexpected token u in JSON at position 0”

store可以直接存任意类型:对象、数组、数字、布尔值,不用处理序列化,也不会有解析错误——比如你存userInfo对象,store.set('userInfo', userInfo)直接存,store.get('userInfo')直接取,省心。

二、store和localStorage不是“二选一”,而是“配合用”

实际项目里,store和localStorage是互补关系,不是互斥的:

  • store管“实时状态”:比如isLogin(登录状态)、currentPage(当前页面)、popupShow(弹窗显示状态)——这些需要实时同步、频繁读写的状态,用store管理,保证实时性和效率。
  • localStorage管“持久化”:比如token(登录凭证)、userInfo(用户信息)——这些需要重启小程序后不丢失的状态,在store更新时同步存到localStorage,在小程序启动时从localStorage读回store:
    // store.js:小程序启动时,从localStorage加载持久化数据
    createApp(options) {
      options.onLaunch = function () {
        // 从localStorage读token和userInfo,初始化到store
        const token = wx.getStorageSync('token') || '';
        const userInfo = wx.getStorageSync('userInfo') ? JSON.parse(wx.getStorageSync('userInfo')) : {};
        this.globalData = { token, userInfo, isLogin: !!token };
        store.app = this;
      };
      return options;
    }
    // 登录时,store更新同时同步到localStorage
    loginSuccess(token, userInfo) {
      store.set('token', token);
      store.set('userInfo', userInfo);
      store.set('isLogin', true);
      // 同步持久化
      wx.setStorageSync('token', token);
      wx.setStorageSync('userInfo', JSON.stringify(userInfo));
    }
    

这样既解决了“实时同步”(store的活),又解决了“重启不丢数据”(localStorage的活)——这才是完整的解决方案。

三、总结:不是“脱裤子放屁”,而是“解决痛点”

  • 如果你只需要“存个数据,重启不丢”(比如Token),且不用实时同步(改了之后用户切页面才看得到),那localStorage够用,store确实没必要。
  • 但如果你需要“改了数据,所有页面立刻响应”(比如登录后立刻显示用户头像、退出后立刻隐藏会员按钮),或需要管理“关联状态”(改Token的同时要改isLogin、清空过期时间),那localStorage根本搞不定,必须用store——它帮你省掉了“手动监听、反复读盘、处理序列化”这些脏活累活,让代码更简洁、不易出错。

转自https://juejin.cn/post/7560887055784099890


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