要实现页面“返回不刷新”,需用<KeepAlive>包裹<router-view>,组件须声明name,并用onActivated/onDeactivated替代onMounted/onUnmounted;可通过include、max等属性精细控制缓存。

要实现页面“返回不刷新”,核心是让组件在路由切换时保持状态,而不是每次重新创建和销毁。Vue 3 的组合式 API 配合 <KeepAlive>(即 <keep-alive>)可以高效达成这一目标,但需注意作用范围、缓存条件与生命周期配合。
确保路由组件被 <KeepAlive> 包裹
<KeepAlive> 是 Vue 内置的抽象组件,它不会渲染真实 DOM,只对插槽中的动态组件做缓存管理。最常见用法是在 <router-view> 外层包裹它:
- 在根组件(如
App.vue)中这样写:
<template>
<RouterView v-slot="{ Component }">
<KeepAlive>
<component :is="Component" />
</KeepAlive>
</RouterView>
</template>这样所有匹配的路由组件都会默认被缓存。若只想缓存部分页面,可配合 include 或 exclude 属性(支持组件名字符串、正则或数组)。
给需要缓存的组件设置唯一的 name
<KeepAlive> 依赖组件的 name 选项来识别和复用实例。使用组合式 API 时,必须显式声明组件名:
- 在
setup()中通过defineOptions设置(推荐,Vue 3.3+):
defineOptions({
name: 'UserProfile'
})- 或在
export default中声明(兼容旧版):
export default {
name: 'UserProfile',
setup() { /* ... */ }
}没有 name 的组件无法被 <KeepAlive> 正确缓存,即使包裹了也会退化为普通渲染。
用 onActivated 和 onDeactivated 替代挂载钩子
被 <KeepAlive> 缓存的组件不会重复触发 onMounted/onUnmounted。取而代之的是两个专属生命周期钩子:
-
onActivated:组件被激活(从缓存中进入视图)时执行,适合恢复滚动位置、重新拉取非关键数据、启动定时器等 -
onDeactivated:组件失活(离开视图但未卸载)时执行,适合暂停定时器、保存临时状态、清理副作用
例如,在用户列表页返回时自动滚动到上次位置:
<pre class="brush:php;toolbar:false;">import { onActivated, onDeactivated, ref } from 'vue'
<p>const scrollPosition = ref(0)</p><p>onActivated(() => {
window.scrollTo(0, scrollPosition.value)
})</p><p>onDeactivated(() => {
scrollPosition.value = window.scrollY
})注意缓存边界与手动控制
<KeepAlive> 默认缓存所有匹配组件,但实际项目中常需更精细控制:
- 用
include精确指定缓存哪些路由组件名:<KeepAlive :include="['UserProfile', 'ArticleDetail']> - 用
max限制最大缓存数量(如:max="5"),避免内存堆积 - 需要强制更新某组件时(如用户提交后刷新详情),可通过
key变更触发重新创建:<component :is="Component" :key="route.fullPath" />(慎用,会破坏缓存目的)
另外,嵌套路由、命名视图、transition 套娃等场景下,需确认 <KeepAlive> 是否包裹到了正确的层级——它只缓存其直接子组件。

















