Vue 中的 keep-alive 组件

Vue 中的 keep-alive 组件

keep-alive 是 Vue 内置的一个抽象组件,用于缓存不活动的组件实例,而不是销毁它们。这可以保留组件状态或避免重新渲染,从而提升性能。

核心特性

  1. 组件状态保持 :当组件在 <keep-alive> 中切换时,其状态会被保留
  2. 避免重复渲染:缓存的组件不会重新创建,减少 DOM 操作
  3. 生命周期变化:添加了特殊的生命周期钩子

基本用法

vue 复制代码
<template>
  <div>
    <button @click="currentTab = 'TabA'">Tab A</button>
    <button @click="currentTab = 'TabB'">Tab B</button>
    
    <keep-alive>
      <component :is="currentTab"></component>
    </keep-alive>
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentTab: 'TabA'
    }
  },
  components: {
    TabA: {
      template: '<div>Tab A Content <input placeholder="输入会被保留" /></div>'
    },
    TabB: {
      template: '<div>Tab B Content</div>'
    }
  }
}
</script>

配置属性

1. include - 指定缓存组件
vue 复制代码
<!-- 字符串(逗号分隔) -->
<keep-alive include="ComponentA,ComponentB">
  <component :is="currentComponent"></component>
</keep-alive>

<!-- 正则表达式 -->
<keep-alive :include="/ComponentA|ComponentB/">
  <component :is="currentComponent"></component>
</keep-alive>

<!-- 数组 -->
<keep-alive :include="['ComponentA', 'ComponentB']">
  <component :is="currentComponent"></component>
</keep-alive>
2. exclude - 排除不缓存组件
vue 复制代码
<keep-alive exclude="ComponentC">
  <component :is="currentComponent"></component>
</keep-alive>
3. max - 最大缓存实例数(Vue 2.5.0+)
vue 复制代码
<keep-alive :max="10">
  <component :is="currentComponent"></component>
</keep-alive>

生命周期钩子

<keep-alive> 包裹的组件会获得两个额外的生命周期钩子:

activated
  • 组件被激活时调用
  • 当组件第一次渲染和每次从缓存中重新激活时都会触发
deactivated
  • 组件被停用时调用
  • 当组件被缓存时触发
vue 复制代码
<script>
export default {
  name: 'MyComponent',
  activated() {
    console.log('组件被激活,恢复状态')
    // 例如:重新开始定时器
    this.startTimer()
  },
  deactivated() {
    console.log('组件被停用,进入缓存')
    // 例如:清除定时器
    this.clearTimer()
  },
  methods: {
    startTimer() {
      this.timer = setInterval(() => {
        console.log('定时器执行')
      }, 1000)
    },
    clearTimer() {
      if (this.timer) {
        clearInterval(this.timer)
      }
    }
  },
  // 传统生命周期依然有效
  created() {
    console.log('created - 只在第一次创建时调用')
  },
  mounted() {
    console.log('mounted - 只在第一次挂载时调用')
  }
}
</script>

与 Vue Router 结合使用

vue 复制代码
<template>
  <div id="app">
    <!-- 缓存包含的路由组件 -->
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    
    <!-- 不缓存的路由组件 -->
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>
javascript 复制代码
// router.js
const routes = [
  {
    path: '/home',
    component: Home,
    meta: {
      keepAlive: true  // 需要缓存
    }
  },
  {
    path: '/detail/:id',
    component: Detail,
    meta: {
      keepAlive: false  // 不需要缓存
    }
  }
]

高级用法示例

动态决定是否缓存
vue 复制代码
<template>
  <keep-alive :include="cachedComponents">
    <router-view></router-view>
  </keep-alive>
</template>

<script>
export default {
  data() {
    return {
      cachedComponents: []  // 动态维护需要缓存的组件名
    }
  },
  watch: {
    '$route'(to, from) {
      // 根据路由规则动态添加/移除缓存
      if (to.meta.keepAlive && !this.cachedComponents.includes(to.name)) {
        this.cachedComponents.push(to.name)
      }
    }
  }
}
</script>
配合 transition 使用
vue 复制代码
<transition name="fade" mode="out-in">
  <keep-alive>
    <component :is="currentComponent"></component>
  </keep-alive>
</transition>

实现原理

keep-alive 内部维护一个缓存对象,主要流程:

  1. 首次渲染时,创建组件实例并缓存
  2. 组件切换时,将当前组件标记为 deactivated 并隐藏
  3. 再次切回时,从缓存中取出实例,标记为 activated 并显示
  4. 使用 LRU(最近最少使用)算法管理缓存(当使用 max 时)

注意事项

  1. 组件必须有 name 选项includeexclude 属性通过组件名匹配
  2. 避免内存泄漏 :合理设置 max,及时清理不需要的缓存
  3. 状态一致性 :确保 activated 中恢复的状态是正确的
  4. 异步组件:同样支持,但需要注意加载时机
  5. 与 v-for 使用:不推荐同时使用,可能会导致缓存混乱

适用场景

  1. 标签页切换:保持每个标签页的状态
  2. 表单页面:离开后返回,表单数据不丢失
  3. 列表页 → 详情页:返回列表页时保持滚动位置和过滤条件
  4. 需要大量计算或网络请求的组件:避免重复计算/请求

Vue 3 中的变化

在 Vue 3 中,keep-alive 的使用方式类似,但有细微变化:

  • includeexclude 支持组件实例的 namesetup 函数中的 name
  • 不再支持缓存 <keep-alive> 的直接子元素数组
vue 复制代码
<!-- Vue 3 -->
<router-view v-slot="{ Component }">
  <keep-alive>
    <component :is="Component" v-if="$route.meta.keepAlive" />
  </keep-alive>
  <component :is="Component" v-if="!$route.meta.keepAlive" />
</router-view>

keep-alive 是 Vue 中优化组件性能的重要工具,合理使用可以显著提升用户体验,特别是在需要保持组件状态的场景中。

相关推荐
可问春风_ren2 小时前
Git命令大全
前端·javascript·git·后端
她说彩礼65万2 小时前
Jquery总结
前端·javascript·jquery
得一录2 小时前
ES6核心语法
前端·ecmascript·es6
光影少年2 小时前
前端如何定位组件变化及性能问题
前端·javascript·react.js
芳草萋萋鹦鹉洲哦2 小时前
【Vue 3/Vite】Tailwind CSS稳定版安装替代CDN引入
前端·css·vue.js
许同2 小时前
JS-WPS 自动化办公(4)文件管理+超链接
javascript·自动化·wps
辰同学ovo3 小时前
Pinia极速入门:核心概念与入门指南
前端·javascript·vue.js
余瑜鱼鱼鱼3 小时前
Thread类中run和start的区别
java·开发语言·前端
n 55!w !1083 小时前
js练习作业
开发语言·javascript·ecmascript