Nuxt3对于页面缓存的实现很简单, 在app.vue的NuxtPage组件上添加一个keepalive就可以实现了
但是如果你的两个页面是不同的布局, 这个缓存可能会失效, 同时也会带来一个小问题
以下是一个简单的页面
通过点击上面的模块按钮, 切换模块, 这里会监听模块的切换, 输出”我被请求了”
目前是没有问题的, 点击切换, 方法只会执行一次
现在跳转到另一个布局不同的页面, 比如我的登录页面
再回到首页, 现在点击一次切换, 会出现方法被调用两次的情况
问题推测
之前我就切换布局, KeepAlive失效问题问过Nuxt开发者, 他的回复大概意思就是:
KeepAlive如果自身被重新创建(通过渲染新的/不同的布局),则无法保留组件实例
这是 Vue 的限制
所以我推测问题大概就是切换布局后 , 页面缓存失效了, 但是watch没有失效, 还在继续监听
当然, 在组件失效后不手动移除监听是我书写的不规范, 如果你有记得移除, 就不会遇到我这种问题
问题解决
利用onActivated, onDeactivated钩子, 在页面缓存失活后, 将监听移除, 页面缓存存活时开启监听,
并直接调用startWatch确保刚加载进页面时, 监听也可以正常工作
// 监听当前模块
let watching
const startWatch = () => {
watching = watch(currentModule, () => {
getModuleContent()
})
}
const stopWatch = () => {
if (watching) {
watching()
}
}
startWatch()
onActivated(() => {
startWatch()
})
onDeactivated(() => {
stopWatch()
})
经过这样修改后, 经过测试, 刚进入页面或者跳转到其他布局任意的页面再回来, watch都可以正常监听, 不会重复工作
写完这个文章后, 又经过我的后来多次测试, 我感觉Nuxt3的keepalive + 多布局会是一个大坑, 如果你有多个布局, 并且多处使用监听器, 我建议不要用keepalive, 可能会有意想不到的问题, 如果你有更好的解决方法, 欢迎在评论区回复一下, 互相学习😉