应优先用 uni.setStorage 存关键数据、uni.setStorageSync 存小且稳定的配置项;存对象需手动 JSON.stringify/parse;各端存储隔离,跨端不可互通;注意 10MB 限制及 HTTP 缓存残留。
直接用 uni.setstorage 或 uni.setstoragesync 就能存,但选错方式、漏掉序列化、忽略跨端隔离,数据大概率会“存了等于没存”。
uni.setStorage 和 uni.setStorageSync 怎么选?
不是看哪个写起来顺手,而是看数据大小、执行时机和错误容忍度。
-
uni.setStorageSync会阻塞 JS 线程,适合存小数据(比如开关状态、语言偏好、单个字符串 token),且必须确保调用时上下文稳定(如不能在异步回调里嵌套多次同步写) -
uni.setStorage不阻塞,但 success 回调才是真正的“写入完成点”,适合存用户信息、token、列表草稿等关键数据;若在 success 外立刻uni.getStorageSync读,很可能拿到旧值或undefined - 混用风险:同一 key 先用
uni.setStorage异步写,再用uni.getStorageSync同步读——低性能设备上极易读空,应统一用异步链或加 Promise 封装
存对象/数组时为什么取出来是 undefined?
因为 uni.setStorage 和 uni.setStorageSync 内部会自动 JSON 序列化,但只对可序列化类型生效。Date、RegExp、Function、undefined、循环引用都会被静默丢弃或转成 null。
- 必须手动
JSON.stringify()再传入:uni.setStorageSync('user', JSON.stringify({ name: '张三', loginTime: new Date() })) - 读取后必须手动
JSON.parse():const user = JSON.parse(uni.getStorageSync('user') || '{}') - 别依赖 try-catch 捕获序列化失败——它不抛错,只是存了个空字符串或
null,后续JSON.parse('')会直接报错
为什么 H5 能读到、小程序却读不到?
各端存储完全隔离:uni.setStorage 在微信小程序里写入的数据,H5 端、App 端、支付宝小程序都访问不到,反之亦然。这不是 bug,是设计。
- 开发调试时,别在 H5 页面里测试小程序的缓存逻辑,否则永远查不到值
- 跨端项目中,不要假设 “存一次,全端可用”,得按平台分别处理或改用后端 session + 短期本地 key 做桥接
- App 端还额外有 WebView 缓存、HTTP DNS 缓存等,
uni.clearStorage()只清uni.*Storage*数据,不会动这些——登出后仍有旧页面残留,往往是因为这个
清缓存时最常误删的关键点
uni.clearStorageSync() 是全局清空,但真正危险的不是它,而是“以为清了就干净了”的错觉。
-
uni.removeStorageSync('token')删除的是 key 为'token'的项,大小写敏感,'Token'或'token '(带空格)都删不掉 - 用了
vuex-persistedstate插件?它底层也走uni.setStorageSync,clearStorageSync会连它的状态一起抹掉 - App 端退出登录时,只删
token和userInfo是不够的——如果请求层(如uni.request)开了 HTTP 缓存,下次请求可能直接返回旧响应,需配合cache: 'no-cache'或时间戳参数规避
10MB 限制不是理论值,iOS 微信小程序实际撑不过 6MB;base64 图片、离线 HTML 片段、未压缩日志最容易爆掉——存之前先 JSON.stringify(data).length 估算下体积,比事后排查 fail 更省事。











