vue3 - 内置组件KeepAlive优化组件状态缓存

文章目录

    • [1. `KeepAlive` 的基本用法](#1. KeepAlive 的基本用法)
    • [2. `KeepAlive` 的工作原理](#2. KeepAlive 的工作原理)
    • [3. `KeepAlive` 的属性](#3. KeepAlive 的属性)
      • [3.1. `include` 和 `exclude`](#3.1. includeexclude)
      • [示例:`include` 和 `exclude`](#示例:includeexclude)
      • 解释:
      • [3.2. `max` 属性](#3.2. max 属性)
      • 示例:`max`
      • 解释:
    • [4. `KeepAlive` 的生命周期钩子](#4. KeepAlive 的生命周期钩子)
      • [示例:使用 `activated` 和 `deactivated`](#示例:使用 activateddeactivated)
      • 解释:
    • [5. `KeepAlive` 的应用场景](#5. KeepAlive 的应用场景)

KeepAlive 是 Vue 提供的一个内置组件,主要用于 缓存 组件的状态。当组件被切换时, KeepAlive 可以保持组件的状态,而不是销毁并重新创建它们,适用于页面切换时 需要保留状态 的场景,如表单、输入框等内容。从而提升应用性能并改善用户体验。

在 SPA(单页应用)中,通常有许多页面或视图,用户在不同页面之间切换时,默认情况下组件会被销毁并重新创建。这样做虽然能保证每次进入页面时都渲染最新的内容,但如果某些页面的状态非常复杂,或者页面中有大量的数据加载与计算,那么每次切换都重新创建组件可能会导致性能问题。

1. KeepAlive 的基本用法

示例:基础用法

vue 复制代码
<template>
  <div>
    <button @click="currentPage = 'page1'">Page 1</button>
    <button @click="currentPage = 'page2'">Page 2</button>

    <keep-alive>
      <component :is="currentPage" />
    </keep-alive>
  </div>
</template>

<script>
import Page1 from "./Page1.vue";
import Page2 from "./Page2.vue";

export default {
  components: { Page1, Page2 },
  data() {
    return {
      currentPage: "page1"
    };
  }
};
</script>

解释:

  • KeepAlive 包裹住 component,从而缓存 Page1Page2 组件的状态。
  • 当用户切换页面时,Page1Page2 不会被销毁,而是会被缓存,保留其状态。

2. KeepAlive 的工作原理

Vue 通过 KeepAlive 组件为 动态组件 提供缓存支持。当组件被包裹在 KeepAlive 中时,它会缓存已经渲染的组件实例。下次访问该组件时,Vue 会 复用已缓存的组件,而不是重新创建新的实例。

工作流程:

  1. 组件渲染时,KeepAlive 会通过 缓存机制 维护每个动态组件的实例。
  2. 当组件离开视图时,KeepAlive 会将该组件的实例保存到内存中。
  3. 组件再次进入视图时,KeepAlive复用缓存的实例,并恢复它的状态。

3. KeepAlive 的属性

KeepAlive 组件提供了一些 属性,以控制缓存的行为。

3.1. includeexclude

  • include:指定缓存哪些组件。可以使用字符串、正则表达式或数组来指定。
  • exclude :指定不缓存哪些组件,功能与 include 类似。

这两个属性可以让你 灵活控制哪些组件应该被缓存,哪些组件应该被排除

示例:includeexclude

vue 复制代码
<template>
  <div>
    <button @click="currentPage = 'page1'">Page 1</button>
    <button @click="currentPage = 'page2'">Page 2</button>
    <button @click="currentPage = 'page3'">Page 3</button>

    <keep-alive :include="['page1']">
      <component :is="currentPage" />
    </keep-alive>
  </div>
</template>

<script>
import Page1 from "./Page1.vue";
import Page2 from "./Page2.vue";
import Page3 from "./Page3.vue";

export default {
  components: { Page1, Page2, Page3 },
  data() {
    return {
      currentPage: "page1"
    };
  }
};
</script>

解释:

  • include="['page1']" 只缓存 Page1 组件。当切换到 Page2Page3 时,它们不会被缓存。

3.2. max 属性

max 属性指定了 缓存的最大数量,当缓存数量超过这个数时,最旧的组件将被销毁。适用于有大量动态组件的情况,防止缓存过多组件占用内存。

示例:max

vue 复制代码
<template>
  <div>
    <button @click="currentPage = 'page1'">Page 1</button>
    <button @click="currentPage = 'page2'">Page 2</button>

    <keep-alive :max="2">
      <component :is="currentPage" />
    </keep-alive>
  </div>
</template>

解释:

  • max="2" 限制最多缓存 2 个组件,当缓存数达到上限时,最早的缓存组件会被销毁。

4. KeepAlive 的生命周期钩子

KeepAlive 中,组件在 激活 (进入视图)和 停用(离开视图)时,都会触发生命周期钩子。Vue 提供了两个生命周期钩子来帮助开发者处理缓存组件的状态:

  • activated:当组件被激活并添加到 DOM 时调用。
  • deactivated:当组件被停用并从 DOM 中移除时调用。

这些钩子通常用于 重置组件的状态清理资源

示例:使用 activateddeactivated

vue 复制代码
<template>
  <keep-alive>
    <component :is="currentPage" />
  </keep-alive>
</template>

<script>
import { ref } from "vue";
import Page1 from "./Page1.vue";
import Page2 from "./Page2.vue";

export default {
  components: { Page1, Page2 },
  data() {
    return {
      currentPage: ref("page1")
    };
  },
  methods: {
    activated() {
      console.log(`${this.currentPage} activated`);
    },
    deactivated() {
      console.log(`${this.currentPage} deactivated`);
    }
  }
};
</script>

解释:

  • activateddeactivated 会在组件进入和离开视图时分别触发,你可以在这两个钩子中做一些状态重置或清理操作。

5. KeepAlive 的应用场景

KeepAlive 主要用于 需要频繁切换的组件,例如:

  • 页面切换:在多页面应用中,切换页面时不希望丢失某些页面的状态。
  • 表单:在表单页面中,表单的输入状态可能需要保留。
  • 选项卡式布局:在选项卡布局中,切换选项卡时不希望重新加载每个选项卡的内容。

示例:常见应用

假设有一个应用,包含多个页面,用户切换页面时,应用通过 KeepAlive 来保持页面状态,而不是重新加载页面。

vue 复制代码
<template>
  <div>
    <keep-alive :include="['page1', 'page2']">
      <component :is="currentPage" />
    </keep-alive>
  </div>
</template>

<script>
import { ref } from "vue";
import Page1 from "./Page1.vue";
import Page2 from "./Page2.vue";
import Page3 from "./Page3.vue";

export default {
  components: { Page1, Page2, Page3 },
  data() {
    return {
      currentPage: ref("page1")
    };
  }
};
</script>

在这个例子中,只有 Page1Page2 被缓存,Page3 每次切换时都会重新加载。


👉点击进入 我的网站

相关推荐
MonkeyKing71553 小时前
Flutter状态管理实战:全局、局部、页面状态拆分指南
前端·flutter
Panzer_Jack3 小时前
Copiwaifu:一个和 Claude Code、Codex、Copilot 等 AI 编程工具联动的 Live2D 桌宠[特殊字符]
前端·人工智能·copilot·web·live2d·pixi.js·easy-live2d
阿维的博客日记3 小时前
Redis 和 Caffeine 构建的多级缓存,如何保持数据一致性?
数据库·redis·缓存
开源情报局4 小时前
从小红书评论区挖需求:我准备用 opencode 写一个 Chrome 插件
前端·javascript·chrome
用户125758524364 小时前
XYGo Admin 三级权限体系:RBAC 动态路由 + v-auth 按钮控制 + 字段级过滤全解析
前端
小李子呢02114 小时前
前端八股JS---Map / Set / WeakMap / WeakSet
开发语言·前端·javascript
冴羽4 小时前
3 招让你的 Shadcn 出海应用性能提升 40 倍
前端·javascript·next.js
中议视控4 小时前
网络中控系统通过推流软件实现可视化:RTSP,H265,WEB等推流
前端·网络
Hsuna4 小时前
Tailwind CSS 比起传统CSS框架无法实现的一些功能
前端·react.js