• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • KeepAlive 缓存组件

    <KeepAlive>是一个内置组件,它的功能是在多个组件间动态切换时,缓存被移除的组件实例。

    基本使用

    在组件基础章节中,我们已经介绍了通过特殊的<component>元素来实现动态组件的用法:

    <component :is="activeComponent" />
    

    默认情况下,一个正活跃的组件实例会在切走后被卸载。这会导致它丢失其中所有已变化的状态,当这个组件再次被显示时,只会创建一个带有初始状态的新实例。

    在下面的例子中,你会看到两个有状态的组件,A 有一个计数器,而 B 有一个通过v-model同步input框输入内容的文字展示。尝试先更改一下任意一个组件的状态,然后切走,再切回来:

    你会发现在切回来之后,之前已更改的状态都被重置了。

    在切换时创建新的组件实例通常是有意义的,但在这个例子中,我们的确想要组件能在被“切走”的时候保留它们的状态。要解决这个问题,我们可以用<KeepAlive>内置组件将这些动态组件包装起来:

    <!-- 非活跃状态的组件将会被缓存! -->
    <KeepAlive>
      <component :is="activeComponent" />
    </KeepAlive>
    
    当你在 DOM 模板中使用时,它应该被写为<keep-alive>


    <keep-alive>包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。<keep-alive>是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。在<script setup>下,当组件在<keep-alive>内被切换时,它的onMountedonUnmounted生命周期钩子不会被调用,取而代之的是onActivatedonDeactivated。(这会运用在<keep-alive>的直接子节点及其所有子孙节点。)

    主要用于保留组件状态避免重新渲染

    <!-- 基本 -->
    <KeepAlive>
      <component :is="view" />
    </KeepAlive>
    
    <!-- 多个条件判断的子组件 -->
    <KeepAlive>
      <componentA v-if="a > 1" />
      <componentB v-else />
    </KeepAlive>
    
    <!-- 和 `<transition>` 一起使用 -->
    <transition>
      <KeepAlive>
        <component :is="view" />
      </KeepAlive>
    </transition>
    



    包含/排除

    默认情况下,<KeepAlive>会缓存内部的所有组件实例。但我们可以通过includeexclude prop 来定制该行为。这两个 prop 的值

    • 一个以,(英文逗号)分隔的字符串
    • 一个正则表达式
    • 包含以上两个类型的一个数组
    <!-- 以英文逗号分隔的字符串 -->
    <KeepAlive include="a,b">
      <component :is="view"></component>
    </KeepAlive>
    
    <!-- 正则表达式(需使用 `v-bind`) -->
    <KeepAlive :include="/a|b/">
      <component :is="view"></component>
    </KeepAlive>
    
    <!-- 数组(需使用 `v-bind`)-->
    <KeepAlive :include="['a', 'b']">
      <component :is="view"></component>
    </KeepAlive>
    

    它会根据组件的name选项进行匹配,所以要想通过KeepAlive有条件地缓存的组件必须显式声明一个name选项

    在 vue 3.2.34 或以上的版本中,使用<script setup>的单文件组件会自动根据文件名生成对应的name选项,无需再手动声明。


    最大缓存实例

    我们可以通过传入max prop 来限制组件缓存的最大数量。当指定了max时,<KeepAlive>会像一个LRU 缓存:如果缓存实例的数量即将超过指定的最大数量,最近访问次数最少的缓存实例将被销毁,以便为新的实例腾出空间。

    <KeepAlive :max="10">
      <component :is="activeComponent" />
    </KeepAlive>
    


    缓存实例的生命周期

    <KeepAlive>缓存而仍作为组件树的一部分时,它将变为不活跃状态而不是被卸载。当一个组件实例作为缓存树的一部分插入到 DOM 中时,它将重新被激活

    一个持续存在的组件可以通过onActivated()onDeactivated()注册相应的两个状态的生命周期钩子:

    <script setup>
    import { onActivated, onDeactivated } from 'vue'
    
    onActivated(() => {
      // 在首次挂载、 以及每次从缓存中重新被插入回 DOM 的时候调用
    })
    
    onDeactivated(() => {
      // 在从 DOM 上移除、进入缓存 以及组件卸载时调用
    })
    </script>
    

    请注意:

    • onActivated在组件挂载时也会调用,并且onDectivated在组件卸载时也会调用。
    • 这两个钩子不仅适用于<KeepAlive>缓存的根组件,也适用于缓存树中的后代组件。