Vue keep-alive 的核心原理

keep-alive 是 Vue 内置的抽象组件,通过缓存不活动的组件实例来优化性能。它利用 LRU(最近最少使用)算法管理缓存,确保内存不被过度占用。

组件被包裹在 keep-alive 中时会多出两个生命周期钩子:activated 和 deactivated。前者在组件被激活时触发,后者在组件被停用时触发。

实现组件缓存的具体方法

为 router-view 添加 keep-alive 包裹:

<keep-alive>
  <router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />

在路由配置中设置 meta 属性:

{
  path: '/detail',
  component: Detail,
  meta: { keepAlive: true }
}

动态控制缓存的技巧

使用 include/exclude 属性精确控制缓存:

<keep-alive :include="['Home', 'Profile']">
  <component :is="currentComponent" />
</keep-alive>

通过编程方式清除缓存:

// 获取 keep-alive 实例
const cache = this.$parent.$children
  .find(child => child.$options.name === 'KeepAlive').cache
// 清除特定组件缓存
delete cache['componentName']

性能优化的最佳实践

设置 max 属性限制最大缓存数:

<keep-alive :max="5">
  <router-view />
</keep-alive>

结合 v-show 处理动态组件:

<keep-alive>
  <component-a v-show="active === 'a'" />
  <component-b v-show="active === 'b'" />
</keep-alive>

对于带参数的路由组件,需要重写 key 计算逻辑:

<router-view v-slot="{ Component }">
  <keep-alive>
    <component :is="Component" :key="$route.path" />
  </keep-alive>
</router-view>

常见问题解决方案

处理滚动位置恢复:

deactivated() {
  this.scrollTop = document.documentElement.scrollTop
},
activated() {
  window.scrollTo(0, this.scrollTop)
}

避免表单数据冲突:

activated() {
  // 重置表单数据
  this.form = cloneDeep(this.initialForm)
}

处理异步数据刷新:

activated() {
  if (this.$route.query.forceRefresh) {
    this.fetchData()
  }
}
Logo

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

更多推荐