uni.setstoragesync写入后重启丢失,主因是key错误或值类型不合法(仅支持json可序列化类型),需用json.stringify校验;读取时应兜底处理为[],且避免在data()中直接初始化,应在onload/onshow中读取。

uni.setStorageSync 写入数据时为什么没生效
直接调用 uni.setStorageSync 却发现重启 App 后数据丢失,大概率是没写对 key 或值类型不合法。它只接受字符串、数字、布尔、对象、数组这五种 JSON 可序列化的类型,Date、RegExp、undefined、函数等都会被静默丢弃(不报错但存的是空值)。
- 确保待存数据先用
JSON.stringify检查是否可序列化,比如{ id: 1, text: '买菜', done: false, createdAt: new Date() }必须手动把createdAt转成字符串 - key 名建议统一前缀,如
'todo-list',避免和其它模块冲突 - 写入后可用
uni.getStorageSync('todo-list')立即读取验证,别等重启再测
用 uni.getStorageSync 读取列表时返回 undefined
这是最常踩的坑:首次运行时 key 根本不存在,uni.getStorageSync 返回 undefined,而不是空数组。如果直接用 .map() 或 .length 就会报 Cannot read property 'map' of undefined。
- 必须做兜底处理:
const list = uni.getStorageSync('todo-list') || [] - 不要在
data()里直接写list: uni.getStorageSync('todo-list')—— Vue 初始化时可能还没完成存储初始化,应改在onLoad或onShow中读取并this.list = ... - 真机调试时注意:H5 端用的是 localStorage,小程序端用的是独立存储空间,两者不互通,别在 H5 测试完就默认小程序也行
删除或修改某条待办后页面不更新
Vue 响应式对数组索引赋值(如 list[0] = newItem)和直接 length 赋值(如 list.length = 0)是不监听的,所以视图不会刷新。
- 新增用
this.list.push(item)或[...this.list, item]都可以触发更新 - 删除某一项推荐用
splice:this.list.splice(index, 1),或用 filter:this.list = this.list.filter((_, i) => i !== index) - 修改某项别直接改原对象属性(如
this.list[0].done = true),而要用Vue.set(this.list[0], 'done', true),或者整个替换:this.list = this.list.map((item, i) => i === index ? {...item, done: true} : item)
跨页面同步数据时 getStorage 拿到旧值
比如在 A 页面添加一条,跳转到 B 页面再读,结果还是旧列表 —— 因为 B 页面的 onLoad 执行时,A 页面的 setStorageSync 可能还没写完(虽然概率低),更常见的是 B 页面缓存了上一次读取的结果,没重新拉取。
- 不要依赖“写完就立刻能读”,尤其在异步跳转场景;B 页面应在
onShow中重新读取,而不是只在onLoad读一次 - 如果涉及多个页面频繁读写,建议封装一个工具函数,比如
loadTodos()和saveTodos(list),内部统一处理空值、序列化、错误提示 - 小程序真机上
uni.setStorageSync是同步阻塞的,但 H5 端底层是异步的 localStorage,所以混合开发时务必加容错,比如写完后延时 10ms 再读(仅调试用,正式环境靠onShow重载更稳妥)











