在 Vue 3 中,路由组件复用(缓存)可能导致 onMounted 生命周期钩子未被触发。以下是解决方案:
问题原因
当路由路径变化但组件相同时(例如从 /detail/1 到 /detail/2),Vue Router 会复用组件实例,导致:
onMounted不会重新执行- 组件内部状态保留
解决方案
方案1:强制重新渲染
通过 key 绑定路由路径强制销毁/重建组件:
vue
<template>
<router-view :key="$route.fullPath" />
</template>
方案2:监听路由变化
在组合式 API 中使用 watch 监听路由参数:
vue
<script setup>
import { watch, onMounted } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
// 首次加载
onMounted(() => {
console.log('ID变化:', route.params.id)
// 数据加载等操作...
})
// 路由参数变化监听
watch(() => route.params.id, (newId) => {
if (newId) {
// 数据操作
}
})
</script>
方案3:使用路由导航守卫
在组件内定义导航守卫:
vue
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
onBeforeRouteUpdate((to, from) => {
// 处理参数变化逻辑
loadData(to.params.id)
})
</script>
注意事项
-
keep-alive缓存 :若使用<keep-alive>包裹路由视图,需配合onActivated钩子:vue<script setup> import { onActivated } from 'vue' onActivated(() => { // 缓存重新激活时执行 }) </script> -
性能权衡:方案1会完全销毁重建组件,频繁切换可能影响性能
建议优先采用方案2或方案3实现数据更新逻辑,仅在必要时使用方案1。