在 Vue 3 中,使用 <keep-alive> 缓存路由组件时,会导致常规的生命周期钩子(如 onBeforeUnmount)无法触发。以下是解决方案:

问题原因

当组件被 <keep-alive> 包裹时:

  • 首次加载时触发 onMounted
  • 离开页面时不会触发 onBeforeUnmountonUnmounted
  • 再次进入页面时触发 onActivated(激活)
  • 再次离开时触发 onDeactivated(休眠)

解决方案

使用 Vue 为缓存组件提供的专属钩子:

import { onActivated, onDeactivated } from 'vue'

setup() {
  // 激活时执行(替代 onMounted)
  onActivated(() => {
    console.log('组件激活')
  })

  // 休眠时执行(替代 onBeforeUnmount)
  onDeactivated(() => {
    console.log('组件休眠')
    // 在此执行清理操作
  })
}

特殊场景处理

若需同时兼容缓存与非缓存状态:

import { onMounted, onUnmounted, onDeactivated } from 'vue'

setup() {
  // 通用初始化
  const init = () => { /* ... */ }
  
  onMounted(init)
  onActivated(init)

  // 双重清理保证
  onUnmounted(() => { /* 最终清理 */ })
  onDeactivated(() => { /* 临时清理 */ })
}

路由配置建议

在路由元信息中声明缓存策略:

const routes = [
  {
    path: '/detail/:id',
    component: Detail,
    meta: {
      keepAlive: true // 通过此标记控制缓存
    }
  }
]

缓存控制技巧

通过 include 属性精确控制缓存:

<router-view v-slot="{ Component }">
  <keep-alive :include="['Home', 'Detail']">
    <component :is="Component" />
  </keep-alive>
</router-view>

关键提示:对于定时器、WebSocket 连接等需要及时释放的资源,务必在 onDeactivated 中处理,避免内存泄漏。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐