全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-20 6 分钟 ✍️ juanwangdev

keep-alive缓存

keep-alive 是 Vue 的内置组件,用于缓存动态组件或路由切换时的组件实例,避免重复渲染。

基本用法

vue
<template>
  <keep-alive>
    <component :is="currentTab" />
  </keep-alive>
</template>

<script setup>
import { ref } from 'vue'
const currentTab = ref('TabA')
</script>

切换 tab 时,组件不会被销毁,而是缓存起来。

include 与 exclude

vue
<!-- 只缓存指定组件 -->
<keep-alive :include="['TabA', 'TabB']">
  <component :is="currentTab" />
</keep-alive>

<!-- 排除指定组件 -->
<keep-alive :exclude="['Settings']">
  <router-view />
</keep-alive>

<!-- 使用正则表达式 -->
<keep-alive :include="/^Tab/">
  <component :is="currentTab" />
</keep-alive>

max 缓存数量限制

vue
<!-- 最多缓存 10 个组件超出时销毁最早缓存的 -->
<keep-alive :max="10">
  <router-view />
</keep-alive>

生命周期钩子

JavaScript
export default {
  data() {
    return { count: 0 }
  },
  created() {
    console.log('created')  // 仅首次创建时触发
  },
  mounted() {
    console.log('mounted')  // 仅首次挂载时触发
  },
  activated() {
    console.log('activated') // 每次激活时触发
  },
  deactivated() {
    console.log('deactivated') // 每次缓存时触发
  },
  beforeUnmount() {
    console.log('beforeUnmount') // 仅真正销毁时触发
  }
}

路由中的 keep-alive

JavaScript
// router/index.js
const routes = [
  {
    path: '/list',
    component: List,
    meta: { keepAlive: true }  // 标记需要缓存
  }
]
vue
<!-- App.vue -->
<router-view v-slot="{ Component }">
  <keep-alive>
    <component :is="Component" />
  </keep-alive>
</router-view>

缓存机制原理

JavaScript
// keep-alive 内部实现简化
const KeepAlive = {
  props: ['max', 'include', 'exclude'],
  setup(props, { slots }) {
    const cache = new Map()      // 缓存组件实例
    const keys = []              // 缓存key列表
    
    return () => {
      const vnode = slots.default()?.[0]
      const key = vnode.key || vnode.type.name
      
      if (cache.has(key)) {
        // 命中缓存,复用实例
        const cached = cache.get(key)
        vnode.componentInstance = cached.instance
        // LRU: 移到末尾
        keys.splice(keys.indexOf(key), 1)
        keys.push(key)
      } else {
        // 未命中,创建并缓存
        cache.set(key, vnode)
        keys.push(key)
        
        // 超出max,销毁最老的
        if (props.max && keys.length > props.max) {
          pruneCache(cache, keys[0])
          keys.shift()
        }
      }
      return vnode
    }
  }
}

清除缓存

JavaScript
// 手动清除指定组件缓存
const removeCacheEntry = (key) => {
  delete cache[key]
  const idx = keys.indexOf(key)
  if (idx > -1) keys.splice(idx, 1)
}

要点总结

  • keep-alive 缓存组件实例,避免重复创建
  • 使用 include/exclude 精确控制缓存范围
  • max 限制缓存数量,使用 LRU 策略淘汰
  • 缓存组件使用 activated/deactivated 钩子
  • 路由切换时配合 router-view 实现页面缓存

📝 发现内容有误?点击此处直接编辑

← 上一篇 过度动画基础
下一篇 → v-for与key的作用
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库