Vue的缓存组件 | 详解KeepAlive

news2024/11/17 15:39:58

引言

Vue开发中,我们经常需要处理大量的组件渲染和销毁操作,这可能会影响应用的性能和用户体验。而VueKeepAlive组件提供了一种简便的方式来优化组件的渲染和销毁流程,通过缓存已经渲染的组件来提升应用的性能。

本文将详细介绍VueKeepAlive组件,探讨其原理和用法。我们将首先了解KeepAlive组件的作用和优势,在什么情况下使用它能够带来性提升。然后,我们将学习如何使用KeepAlive组件缓存需要保持状态的组件,以及如何通过生命周期钩子函数来控制缓存的组件。我们还会介绍KeepAlive与动态组件、路由组件的搭配使用,以及其在列表渲染中的应用。

通过本文的学习,您将了解到如何灵活运用KeepAlive组件来优化Vue应用的性能。您将掌握到如何合理地使用缓存组件,以及其与其他Vue特性的结合使用,来构建出更高效、流畅的应用。让我们一起深入探索Vue的缓存组件KeepAlive

以下是本文的目录

一. keep-alive 的作用

二. keep-alive 的原理

三. keep-alive 的应用

四. keep-alive 的刷新

五. keep-alive 页面缓存思路

一. keep-alive 的作用

首先引用官网文档介绍:keep-alive官方文档

Vuekeep-alive为抽象组件,主要用于缓存内部组件数据状态。可以将组件缓存起来并在需要时重新使用,而不是每次重新创建。这可以提高应用的性能和用户体验,特别是在需要频繁切换组件时。

Props: include - 字符串或正则表达式。只有名称匹配的组件会被缓存。 exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。 max - 数字。最多可以缓存多少组件实例。

用法:

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。

当组件在 <keep-alive> 内被切换,它的 activateddeactivated 这两个生命周期钩子函数将会被对应执行。

通常情况下,组件在销毁时会释放它所占用的资源,如 DOM 元素、监听器、定时器等。而当组件需要重新使用时,需要重新创建这些资源,这会消耗额外的时间和性能。

使用 keep-alive 组件可以避免这种情况,它可以将组件缓存起来并在需要时直接使用,而不需要重新创建。这样可以节省资源和提高性能,特别是对于那些需要频繁切换的组件,比如 Tab 切换、路由切换等等。

另外,keep-alive 组件也提供了一些钩子函数,可以用来在组件激活和失活时执行一些操作,比如更新数据、发送请求等等。这些钩子函数包括:

  • activated: 组件被激活时调用,可以用来更新数据等操作。

  • deactivated: 组件被缓存时调用,可以用来清除数据等操作。

需要注意的是:keep-alive 组件只能缓存有状态组件,不能缓存无状态组件(比如纯展示组件)。此外,如果需要缓存多个组件,需要使用 v-for 循环遍历,而且每个缓存的组件必须有一个唯一的 key 属性。

总之,keep-alive 组件可以提高应用的性能和用户体验,特别是在需要频繁切换组件时。但需要注意使用时的细节和限制。

二. keep-alive 的原理

keep-alive 组件的实现原理是将被缓存的组件实例存储到一个缓存对象中,当需要重新渲染这个组件时,会从缓存中获取到之前的实例,并将其重新挂载到 DOM 上。

Vue的渲染看keep-alive的渲染

713-2.png

Vue的渲染是从图中render阶段开始的
keep-alive的渲染是在patch阶段(构建组件树(虚拟DOM树),并将VNode转换成真正DOM节点的过程)

image.png

1、在首次加载被包裹组件时,由keep-alive.js中的render函数可知,vnode.componentInstance的值是undfinedkeepAlive的值是true,因为keep-alive组件作为父组件,它的render函数会先于被包裹组件执行;那么只执行到i(vnode,false),后面的逻辑不执行;

2、再次访问被包裹组件时,vnode.componentInstance的值就是已经缓存的组件实例,那么会执行insert(parentElm, vnode.elm, refElm)逻辑,这样就直接把上一次的DOM插入到父元素中。

713-1.png

三. keep-alive 的应用

下面是一个简单的例子,演示了如何使用 keep-alive 组件缓存一个计数器组件:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script>
export default {
  props: ['count'],
  methods: {
    increment() {
      this.$emit('increment')
    },
    decrement() {
      this.$emit('decrement')
    },
    reset() {
      this.$emit('reset')
    }
  }
}
</script>

父组件使用

<template>
  <div>
    <keep-alive>
      <counter :count="count" @increment="increment" @decrement="decrement" @reset="reset" />
    </keep-alive>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script>
import Counter from './Counter.vue'

export default {
  components: {
    Counter
  },
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    },
    reset() {
      this.count = 0
    }
  }
}
</script>

在这个例子中,我们创建了一个计数器组件 Counter,并在父组件中使用 keep-alive 组件来缓存它。我们还定义了一个 count 数据属性,并将它传递给 Counter 组件作为一个 prop,用于展示当前的计数值。同时,我们还绑定了三个自定义事件 incrementdecrementreset,用于响应计数器的操作。

当我们点击增加或减少按钮时,Counter 组件的 count 属性会发生变化,但由于它被包裹在 keep-alive 组件中,所以实际上并没有被销毁。当我们再次渲染 Counter 组件时,它会从缓存中获取到之前的实例,并将其重新挂载到 DOM 上,这样就能够保留之前的状态。 在上面的例子中,我们可以看到在 keep-alive 组件中只包含了一个 Counter 组件。但是,在实际应用中,我们可能需要缓存多个不同的组件,这时我们可以通过 includeexclude 属性来指定要缓存或排除的组件。

例如,我们可以修改上面的例子,将 Counter 组件和另一个文本组件 Text 都缓存起来

<template>
  <div>
    <keep-alive :include="[Counter, Text]">
      <component :is="currentComponent" :count="count" v-on:increment="increment" v-on:decrement="decrement" v-on:reset="reset" />
    </keep-alive>
    <button @click="toggleComponent">切换</button>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script>
import Counter from './Counter.vue'
import Text from './Text.vue'

export default {
  components: {
    Counter,
    Text
  },
  data() {
    return {
      count: 0,
      currentComponent: 'Counter'
    }
  },
  methods: {
    toggleComponent() {
      this.currentComponent = this.currentComponent === 'Counter' ? 'Text' : 'Counter'
    },
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    },
    reset() {
      this.count = 0
    }
  }
}
</script>

在上面的例子中,我们定义了一个 currentComponent 数据属性,用于动态切换要渲染的组件。我们还使用了 component 元素来动态渲染不同的组件。

keep-alive 组件中,我们使用了 include 属性来指定要缓存的组件。注意,这里传入的是一个数组,可以包含多个组件。

同时,我们还可以使用 exclude 属性来排除某些组件不进行缓存。例如,我们可以将 Text 组件排除在缓存之外,如下所示:

<keep-alive :include="[Counter]" :exclude="[Text]">
  <!-- 缓存 Counter 组件,排除 Text 组件 -->
</keep-alive>

注意事项

KeepAlive组件是一个强大的性能优化工具,但是需要合理使用,并注意其中的一些注意事项。通过深入理解和正确使用KeepAlive组件,才可以在Vue应用中提高性能和用户体验。在使用VueKeepAlive组件时,有一些注意事项需要注意:

  1. 合理使用KeepAlive组件通过缓存已经渲染的组件,可以提升应用的性能。但是,过多地使用KeepAlive组件可能会导致内存占用增加,因此需要谨慎使用。只在真正需要保持组件状态的场景下使用KeepAlive组件。

  2. 控制缓存的组件数量:默认情况下,KeepAlive会缓存所有经过它的子组件。如果不需要缓存所有组件,需要通过includeexclude属性来选择性地缓存组件。这样可以避免不必要的内存占用。

  3. 生命周期的影响:被KeepAlive缓存的组件,会在activateddeactivated生命周期钩子函数中触发相应的逻辑。因此,在使用KeepAlive时,要注意这些生命周期函数的使用场景和影响。

  4. 组件状态更新:由于KeepAlive组件对缓存的组件进行了复用,因此需要小心处理组件状态的更新。一些状态变更操作,可能不会在组件重新激活时触发,需要手动处理相应的逻辑。

  5. 样式与动画:由于KeepAlive组件会复用组件实例,可能会导致一些样式和动画的问题。特别是涉及到组件之间的切换效果时,需要特别注意相关的样式和动画逻辑。

总而言之,keep-alive 组件的作用是缓存动态组件或者组件的状态,避免重复渲染和销毁组件,从而提高应用的性能。在实际应用中,我们可以通过指定要缓存或排除的组件来灵活地控制组件的缓存策略,以满足不同的需求。

四. keep-alive 如何刷新

当使用 keep-alive 组件缓存一个组件时,如果需要在组件被缓存时执行一些操作,可以使用 activated 钩子函数,在组件被激活(被缓存并且被展示)时触发。如果需要在组件被缓存时清除一些数据或状态,可以使用 deactivated 钩子函数,在组件被停用(被缓存但不被展示)时触发。

如果需要强制重新渲染被缓存的组件,可以使用 this.$forceUpdate() 方法。在被缓存的组件中,可以将这个方法绑定到一个按钮上,当按钮被点击时,被缓存的组件会强制重新渲染。

需要注意的是,使用 this.$forceUpdate() 方法会重新渲染整个组件,包括不在 keep-alive 组件中的部分,因此需要谨慎使用,以免影响应用的性能。

除了使用 this.$forceUpdate() 方法强制重新渲染组件外,还可以使用 includeexclude 属性来控制哪些组件应该被缓存或不被缓存。当我们需要更新一个被缓存的组件时,可以将它从缓存中排除,并在需要更新时再重新包含到缓存中。这样可以避免无谓的重复渲染,提高应用的性能。

综上所述,我们可以通过使用 activateddeactivated 钩子函数、this.$forceUpdate() 方法以及 includeexclude 属性来控制被缓存的组件的刷新策略,以满足不同的需求。

五. keep-alive 页面缓存思路

功能需求描述:

  1. 页面前进刷新,后退不刷新

  2. 动态配置可缓存的页面

  3. 手动刷新已缓存的页面

实现思路:动态include配置缓存组件,路由拦截判断当前跳转路由是否配置可缓存

<template>
  <keep-alive :include="cachedViews" :exclude="excludeViews">
    <router-view></router-view>
  </keep-alive>
</template>

动态操作include绑定值store状态管理:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        cachedViews: [],
        excludeViews: []
    },
    mutations: {
        ADD_CACHED_VIEW: (state, payload) => {
          if (state.cachedViews.includes(payload)) return
          state.cachedViews.push(payload)
        },
        DEL_CACHED_VIEW: (state, payload) => {
          const index = state.cachedViews.indexOf(payload)
          index > -1 && state.cachedViews.splice(index, 1)
        }
    },
    actions: {
        ADD_CACHED_VIEW({ commit, }, payload) {
          commit('ADD_CACHED_VIEW', payload)
        },
        DEL_CACHED_VIEW({ commit, }, payload) {
          commit('DEL_CACHED_VIEW', payload)
        }
    }
})

export default store

在路由拦截器中实现逻辑:

  1. 路由导航进入时,如果配置了缓存,则记录状态,并实现缓存页面

import store from '@/store'

router.beforeEach((to, from, next) => {
   if (to.meta.keepAlive) {
     store.dispatch('ADD_CACHED_VIEW', to.name)
   }
})
  1. 路由离开时,删除缓存标识

<script>
export default {
  name: "B",
  beforeRouteLeave(to, from, next) {
    if (to.name != "C") {
      this.$store.dispatch('DEL_CACHED_VIEW', to.name)
    }
    next();
  },
  methods: {
  }
};
</script>

结语

通过本文的学习,我们深入了解了Vue中的缓存组件KeepAlive,并详细介绍了它的原理和使用方法。我们了解了KeepAlive组件的作用,以及通过缓存已经渲染的组件来提升应用性能的优势。

在实际开发中,我们经常会遇到需要保持组件状态的场景,比如在动态组件路由组件或者列表渲染中。使用KeepAlive组件可以很方便地缓存这些组件,并在需要时重新激活,避免了频繁的组件销毁和重新渲染。

同时,我们也提到了KeepAlive组件的一些使用注意事项。由于缓存组件可能导致内存占用增加,所以需要对缓存的组件进行适当管理,避免出现内存泄漏的情况。我们还介绍了如何使用activated和deactivated生命周期钩子函数来控制缓存的组件的行为,以及如何通过excludeinclude属性来选择性地缓存组件。

通过合理地运用KeepAlive组件,我们可以在Vue应用中显著提升性能和用户体验。使用KeepAlive组件不仅能够减少不必要的组件渲染,还能提高页面切换的流畅度,让用户感受到更好的应用响应速度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2133381.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年职场人士PDF转换的新宠儿

PDF文件已经成为日常收发文件的首选项了&#xff0c;它能保证文件页面内容、版式的统一性&#xff0c;但是不太好编辑&#xff0c;所以我们还需要一些小工具来帮我们解决这个问题。今天我们来探讨一下有什么可以从pdf转换器免费版官网下载的工具。 1.Foxit PDF转换大师 链接一…

BuripSuiteProfessional 抓取HTTPS配置

1.电脑拿开代理 谷歌为例 点击三点-设置 -输入代理--点击代理设置 打开手动代理---IP ,端口如图-点击保存 2.下载CA证书 打开代理后,谷歌浏览器打开,输入/burp--如下图-点击CA证书下载证书 选择下载目录--桌面 3.安装CA证书 谷歌浏览器中点开设置-输入证书-点击安全 点击…

Apollo(阿波罗)架构由浅入深剖析

1.最简架构 如果不考虑分布式微服务架构中的服务发现问题,Apollo 的最简架构如下图所示: 注意事项: ConfigService 是一个独立的微服务,服务于 Client 进行配置获取。 Client 和 ConfigService 保持长连接,通过一种拖拉结合 (push & pull) 的模式,实现配置实时更新…

【鸿蒙】HarmonyOS NEXT星河入门到实战8-自定义组件-组件通信

目录 1、模块化语法 1.1 模块化基本认知 1.2 默认导出和导入 1.2.1 在ets下新建tools目录 1.2.2 在tools下新建moduls.ets文件 1.2.3 index.ets 1.3 按需导出和导入 1.4 全部导入 2、自定义组件 -基础 2.1 自定义组件 - 基本使用 2.2 自定义组件 -通用样式 2.2.1 et…

Wophp靶场寻找漏洞练习

1.命令执行漏洞 打开网站划到最下&#xff0c;此处的输入框存在任意命令执行漏洞 输入命令whoami 2.SQL注入 搜索框存在SQL注入&#xff0c;类型为整数型 最终结果可以找到管理员账户和密码 3.任意文件上传漏洞 在进入管理员后台后&#xff0c;上传木马文件 访问该文件&…

【智路】智路OS airos-edge

欢迎来到智路OS https://gitee.com/ZhiluCommunity/airos-edge 智路OS是全球首个开源开放的智能网联路侧单元操作系统&#xff08;简称“智路OS”&#xff09;&#xff0c; 是以高等级自动驾驶技术为牵引&#xff0c;沉淀出来的“车路云网图”一体化的智能交通基础软件平台。…

基于SpringBoot+Vue的智慧自习室预约管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

基于vue框架的宠物店管理系统的设计与实现4czn0(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,商品分类,服务类型,商品信息,商品订单,宠物服务,服务预约,服务评价,商品咨询 开题报告内容 基于Vue框架的宠物店管理系统的设计与实现开题报告 一、引言 随着宠物行业的蓬勃发展&#xff0c;宠物店作为宠物产品与服务的重要提供…

神经网络通俗理解学习笔记(2)循环神经网络RNN

循环神经网络RNN 序列建模自回归模型隐变量自回归模型 文本数据预处理循环神经网络随时间反向传播循环神经网络代码实现RNN的长期依赖问题 序列建模 序列数据-时间 不同时间上收集到的数据&#xff0c;描述现象随时间变化的情况 时间序列分析是指从时间排列的数据点中抽取有价…

Linux下编译Kratos

本文记录在Linux下编译Kratos的流程。 零、环境 操作系统Ubuntu 22.04.4 LTSVS Code1.92.1Git2.34.1GCC11.4.0CMake3.22.1Boost1.74.0oneAPI2024.2.1 一、依赖与代码 1.1 安装依赖 apt-get update apt-get install vim openssh-server openssh-client ssh \build-essential …

Web:HTTP包的相关操作

目录 一、请求包修改页面来源 二、Cookie身份认证 三、XXF修改本地访问 四、向页面同时发出GET和POST请求 一、请求包修改页面来源 题目提示要从 http://localhost:8080/flag3cad.php?a1&#xff0c;请求包中没有指定请求来源&#xff0c;需要指定。 而表示页面来源的字段…

cv2.bitwise_or 提取ROI区域

原图如下所示&#xff0c;想提取圆形ROI区域&#xff0c;红色框 img np.ones(ori_img.shape, dtype"uint8") img img * 255 cv2.circle(img, (50,50), 50, 0, -1) self.bitwiseOr cv2.bitwise_or(ori_img, circle)使用一个和原图尺寸一致的图像做mask,图白圆黑 以…

【Echarts】vue3打开echarts的正确方式

ECharts 是一个功能强大、灵活易用的数据可视化工具&#xff0c;适用于商业报表、数据分析、科研教育等多种场景。那么该如何优雅的使用Echarts呢? 这里以vue3为例。 安装echarts pnpm i echarts封装公用方法 // ts-nocheck import * as echarts from echarts; // 我们这里借…

Naive UI中的时间选择器如何禁止选择今天之前的时间

:is-date-disabled"dateDisabled"<n-date-pickerv-if"formData.timeEndActive"type"date"style"width: 100%"placeholder"请选择任务结束时间"value-format"yyyy-MM-dd 23:59:59":is-date-disabled"dateD…

mysql-搭建主从复制

文章目录 1、准备主服务器2、准备从服务器3、主库配置3.1、创建MySQL主服务器配置文件&#xff1a; 4、从库配置5、搭建主从&测试5.1、使用命令行登录MySQL主服务器5.2、主机中查询master状态&#xff1a;5.3、从机中查询slave状态&#xff1a;5.4、主机中创建slave用户&am…

CSP-J算法基础 树状结构与二叉树

文章目录 前言树状结构树状结构的基本概念&#xff1a;为什么需要树状结构&#xff1f;优点树状结构的示例 二叉树什么是二叉树&#xff1f;二叉树的类型什么样的树不是二叉树&#xff1f;二叉树的五种形态 完全二叉树相关概念完全二叉树的定义&#xff1a; 相关概念1. **高度&…

SAAS智慧工地源码,建筑行业数字化管理云平台系统

智慧工地是建筑行业数字化转型的重要组成部分&#xff0c;它通过集成物联网、大数据、云计算、人工智能等现代信息技术&#xff0c;对建筑工地进行智能化管理&#xff0c;以提高施工效率、保障施工安全、控制施工成本、提升施工质量。 以下是智慧工地的主要特点和应用&#xff…

【油猴脚本】00003案例 Tampermonkey油猴脚本引入css 库,油猴脚本css库的使用

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

通过python提取PDF文件指定页的图片

整体思路 要从 PDF 文件中提取指定页和指定位置的图片&#xff0c;可以分几个步骤来实现&#xff1a; 1.1 准备所需工具与库 在 Python 中处理 PDF 和图像时&#xff0c;需要使用几个库&#xff1a; PyMuPDF (fitz)&#xff1a;用于读取和处理 PDF 文件&#xff0c;可以精确…

【STM32】esp8266连接wifi

1.配置stm32cubemx 使用串口二接收esp8266的数据&#xff0c;单片机接收&#xff0c;使用串口1将数据发送给串口助手 串口2波特率设置74880&#xff0c;串口1设置115200 在初始化的时候需要将复位引脚拉低20ms,然后再拉高20ms, 设置GPIOB的输出模式 对PB12做输出处理 2.…