Vue中KeepAlive组件的优雅运用

一、引言

Vue.js是一款流行的前端框架,它提供了许多方便的特性来帮助我们构建交互式的用户界面。其中一个重要的特性是Keep-Alive组件,它可以在组件切换时保持组件的状态,从而提升用户体验。

二、什么是KeepAlive?

在Vue中,KeepAlive组件是一种特殊的组件,用于缓存已经渲染过的组件实例。它可以将组件保存在内存中,以避免每次重新渲染组件时都执行组件的生命周期钩子函数和重新渲染DOM的开销。

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

三、KeepAlive的基本用法

KeepAlive组件是Vue的内置组件,通过将其包裹在需要缓存的组件外部,可以实现组件状态的保留。

js 复制代码
<template>
  <KeepAlive>
    <component :is="currentComponent"></component>
  </KeepAlive>
</template>

上面的代码示例是通过Vue的<component>元素和特殊的is属性实现的,可以使用:is属性来指定要渲染的组件。:is属性的值可以是一个组件的选项对象,也可以是一个组件的名称。

<component>是一个动态组件,根据currentComponent的值来动态加载不同的子组件。

四、缓存和销毁

默认情况下,KeepAlive会缓存所有传递给它的组件实例,但你可以通过使用includeexclude属性来明确指定哪些组件需要缓存或排除。

js 复制代码
<template>
  <KeepAlive :include="['ComponentA']" :exclude="['ComponentB']">
    <component :is="currentComponent"></component>
  </KeepAlive>
</template>

在上面的代码示例中,ComponentA会被缓存,而ComponentB不会。

通过:include属性,我们可以指定需要缓存的组件,这里使用了数组['ComponentA']来指定只缓存ComponentA组件的实例。

通过:exclude属性,我们可以指定不需要缓存的组件,这里使用了数组['ComponentB']来指定不缓存ComponentB组件的实例。

js 复制代码
<!-- 以英文逗号分隔的字符串 -->
<KeepAlive include="a,b">
  <component :is="view" />
</KeepAlive>

<!-- 正则表达式 (需使用 `v-bind`) -->
<KeepAlive :include="/a|b/">
  <component :is="view" />
</KeepAlive>

<!-- 数组 (需使用 `v-bind`) -->
<KeepAlive :include="['a', 'b']">
  <component :is="view" />
</KeepAlive>

KeepAlive组件的include属性可以接收一个字符串、正则表达式或一个数组,用于指定哪些组件需要被缓存。

  • 字符串:可以是组件的名称,用于指定具体的组件需要被缓存。
  • 正则表达式:可以使用正则表达式来匹配组件的名称,所有匹配成功的组件都会被缓存。
  • 数组:可以包含多个组件名称,用于指定多个组件需要被缓存。

五、最大缓存实例数

我们可以通过传入max值来限制可被缓存的最大组件实例数。

js 复制代码
<KeepAlive :max="10">
  <component :is="activeComponent" />
</KeepAlive>

在上述的代码示例中,如果组件实例数超过10个时(超出了指定的最大数量),就按LRU算法将最长时间没被访问的缓存实例销毁,来为新的实例腾出空间。

六、配合动态组件使用

KeepAlive特别适用于动态组件的场景,它可以保留动态组件的状态,让用户在不同组件之间切换时保持良好的交互体验。

js 复制代码
<template>
  <KeepAlive>
    <component :is="currentComponent"></component>
  </KeepAlive>
</template>

<script>
export default {
  data() {
    return {
      currentComponent: 'ComponentA'
    };
  }
}
</script>

通过:is="currentComponent",我们动态地渲染不同的组件。

currentComponent是一个数据属性,初始值为'ComponentA',表示要渲染的组件是ComponentA。通过改变currentComponent的值,我们可以在运行时切换渲染不同的组件,从而实现动态组件的切换效果。

七、KeepAlive组件的生命周期

KeepAlive组件有自己的生命周期钩子函数,可以在需要时进行操作。一个持续存在的组件可以通过onActivated()和onDeactivated()注册相应的两个状态的生命周期钩子。

  1. onActivated:当组件被激活时调用,对应Vue组件的onActivated钩子函数。
  2. onDeactivated:当组件被停用时调用,对应Vue组件的onDeactivated钩子函数。

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

js 复制代码
<script setup>
import { onActivated, onDeactivated } from 'vue'

onActivated(() => {
  // 在组件被激活时执行的操作
  // 调用时机为首次挂载
  // 以及每次从缓存中被重新插入时
})

onDeactivated(() => {
  // 在组件失效时执行的操作
  // 在从 DOM 上移除、进入缓存
  // 以及组件卸载时调用
})
</script>

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

八、举个例子

让我们通过一个实际的案例来演示KeepAlive的使用。假设我们有一个选项卡切换的页面,每个选项卡对应一个组件。

js 复制代码
<template>
  <div>
    <button @click="toggleTab('TabA')">Tab A</button>
    <button @click="toggleTab('TabB')">Tab B</button>
    <KeepAlive>
      <component :is="currentTab"></component>
    </KeepAlive>
  </div>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

export default {
  components: {
    ComponentA,
    ComponentB
  },
  data() {
    return {
      currentTab: 'ComponentA'
    };
  },
  methods: {
    toggleTab(tab) {
      this.currentTab = tab;
    }
  }
}
</script>

<KeepAlive>标签中,我们使用了动态组件来根据currentTab的值来动态渲染不同的组件。

toggleTab方法用于切换当前的选项卡。当按钮被点击时,会调用该方法,并将对应的选项卡名称作为参数传入。该方法会将currentTab的值更新为传入的选项卡名称,从而实现动态切换选项卡的效果。

九、最后的话

KeepAlive是Vue提供的一个强大工具,能够显著提升应用程序的性能和用户体验。通过合理地运用KeepAlive,我们可以在保持组件状态的同时,提供快速、流畅的用户界面切换效果。

如果对Vue中的插槽(slot)有不清楚,可以去看这篇 Vue中的插槽(Slot)技术详解!

能力一般,水平有限,本文可能存在纰漏或错误,如有问题欢迎指正,感谢你阅读这篇文章,如果你觉得写得还行的话,不要忘记点赞、评论、收藏哦!祝大家生活愉快!

相关推荐
passerby606116 分钟前
完成前端时间处理的另一块版图
前端·github·web components
掘了23 分钟前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅26 分钟前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment1 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税2 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore