uni-app无页面缓存机制,所谓状态残留实为Vue实例未销毁、data未重置或数据存于Storage/全局状态;onUnload仅在页面彻底退出栈时触发,返回时仅onHide,data仍保留;应改用onShow重置关键字段、配合store.$reset()或路由reLaunch彻底销毁实例。

uni-app 没有“页面缓存”这个机制,所谓“页面状态残留”其实是 Vue 实例没销毁、data 没重置、或数据挂在了 Storage / 全局状态里 —— 直接调 uni.clearStorageSync() 或刷新页面,根本清不掉。
为什么 onUnload 不触发,但页面 data 还在?
很多人以为从 B 页 navigateBack 回 A 页,A 的 onUnload 就会执行。实际只有 A 被彻底移出页面栈(比如被 reLaunch 替换、或被系统回收)才会触发。大多数返回场景下,A 只是进入 onHide 状态,this.data 完全保留,组件实例也还在内存里。
常见错误现象:
- 表单页返回再进,输入内容还在
- 搜索页带参数跳转后,
onLoad里直接赋值给data,导致下次进页面自动带上次关键词 - 用了 Pinia/Vuex,但没在
onHide或onUnload主动重置 state
怎么在 onShow 里安全重置页面状态?
适合需要“每次进入都清空”的页面,比如搜索页、新建表单页。关键不是清缓存,而是控制 data 初始化时机。
- 把初始化逻辑从
onLoad搬到onShow,并在里面手动重置关键字段:this.searchKeyword = ''、this.formData = { name: '', phone: '' } - 避免在
onLoad里直接用options赋值给data,改用计算属性或临时变量(如const keyword = options.keyword || ''),防止污染原始 data 结构 - 如果用了 Pinia,记得在
onHide里调store.$reset();Vuex 则 commit'RESET_FORM'类型的 mutation - H5 端尤其注意:
sessionStorage里的表单草稿不会被任何 uni API 清除,得自己sessionStorage.removeItem('draft')
想彻底销毁页面实例?别清缓存,要动路由栈
Vue 组件销毁取决于页面栈是否释放该实例。想让页面真·退出内存,必须让它离开栈,而不是“返回”。
-
uni.reLaunch({ url: '/pages/home/home' }):替换整个栈,原页面实例会被销毁(触发beforeDestroy、onUnload) -
uni.redirectTo({ url: '/pages/list/list' }):只替换当前页,上一页仍保留在栈中但不可见;若需连带销毁上一页,得在上一页主动uni.navigateBack({ delta: 1 })后再redirectTo - 慎用
uni.navigateBack({ delta: 2 })强退多级 —— 若中间页有未保存数据,用户无法挽回
H5 和小程序端最容易漏掉的三类存储
uni.clearStorageSync() 只清 uni.setStorage 写入的数据,以下三类它完全不管,上线后常因此出问题:
- 手动写的
localStorage.setItem('ab_test_group', 'v2')→ 得自己localStorage.removeItem('ab_test_group') -
sessionStorage里的临时数据(如草稿、临时 token)→ 必须显式sessionStorage.clear()或逐个删 - PWA 或自定义 Service Worker 的
caches.open('api-cache')→ uni 无感,得自己调caches.delete('api-cache')
真正麻烦的从来不是“怎么清”,而是“你根本不知道自己往哪存了”。上线前建议全局 grep localStorage、sessionStorage、caches.,一个都不能漏。


















