这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

前言

一. keep-alive 的作用

二. keep-alive 的原理

三. keep-alive 的应用

四. keep-alive 的刷新

五. keep-alive 页面缓存思路

一. keep-alive 的作用

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

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

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

用法:

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

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

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

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

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

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

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

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

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

二. keep-alive 的原理

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

从Vue的渲染看keep-alive的渲染

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

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

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

三. 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>

总之,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.路由导航进入时,如果配置了缓存,则记录状态,并实现缓存页面

2.路由离开时,删除缓存标识

import store from '@/store'

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

本文转载于:

https://juejin.cn/post/7270160291413016628

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--Vue的缓存组件 | 详解KeepAlive的更多相关文章

  1. vue.js基础知识篇(6):组件详解

    第11章:组件详解 组件是Vue.js最推崇也最强大的功能之一,核心目标是可重用性. 我们把组件代码按照template.style.script的拆分方式,放置到对应的.vue文件中. 1.注册 V ...

  2. Angular6 学习笔记——组件详解之组件通讯

    angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...

  3. Tomcat负载均衡、调优核心应用进阶学习笔记(一):tomcat文件目录、页面、架构组件详解、tomcat运行方式、组件介绍、tomcat管理

    文章目录 tomcat文件目录 bin conf lib logs temp webapps work 页面 架构组件详解 tomcat运行方式 组件介绍 tomcat管理 tomcat文件目录 ➜ ...

  4. OpenStack的Swift组件详解

    一:简介     一.背景 1. Swift 最初是由 Rackspace 公司开发的高可用分布式对象存储服务(Object  Storage Service),并于 2010 年贡献给 OpenSt ...

  5. Redis for Windows(C#缓存)配置文件详解

    Redis for Windows(C#缓存)配置文件详解   前言 在上一篇文章中主要介绍了Redis在Windows平台下的下载安装和简单使用http://www.cnblogs.com/aehy ...

  6. Angular6 学习笔记——组件详解之模板语法

    angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...

  7. admin组件详解

    admin组件详解 先根据admin组件启动流程复习下django项目启动至请求过来发生的事 1将admin组件注册进app 2django项目启动 3在运行到定制的admin时执行其下面的apps文 ...

  8. OpenStack各组件详解和通信流程

    一.openstack由来 openstack最早由美国国家航空航天局NASA研发的Nova和Rackspace研发的swift组成.后来以apache许可证授权,旨在为公共及私有云平台建设.open ...

  9. Tomcat系列之服务器的安装与配置以及各组件详解

    Tomcat系列之服务器的安装与配置以及各组件详解 大纲 一.前言 二.安装与配置Tomcat 三.Tomcat 目录的结构 四.Tomcat 配置文件 注,本文的测试的操作系统为CentOS 6.4 ...

  10. Logstash组件详解(input、codec、filter、output)

    logstash组件详解 logstash的概念及特点. 概念:logstash是一个数据采集.加工处理以及传输(输出)的工具. 特点: - 所有类型的数据集中处理 - 不同模式和格式数据的正常化 - ...

随机推荐

  1. JS 前序遍历、中序遍历、后序遍历、层序遍历详解,深度优先与广度优先区别,附leetcode例题题解答案

    壹 ❀ 引 按照一天一题的速度,不知不觉已经刷了快两多月的leetcode了,因为本人较为笨拙,一道简单的题有时候也会研究很久,看着提交了两百多次,其实也才解决了70来道简单题,对于二分法,双指针等也 ...

  2. JS leetcode 翻转字符串里的单词 题解分析

    壹 ❀ 引 今天来做一道难度中等,但实际难度并不是很高的题目,题目来源leetcode151. 翻转字符串里的单词,题目描述如下: 给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: & ...

  3. test-01-java 单元测试框架 junit 入门介绍

    拓展阅读 junit5 系列 基于 junit5 实现 junitperf 源码分析 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息 ...

  4. Atom N2600, N2800 安装 Ubuntu22.04 卡住的问题处理

    问题描述 Atom N2600, N2800 的某些旧型号机器, 安装 Ubuntu 时在安装界面选择安装后, 启动过程中会卡住, 或者数秒即黑屏, 再无反应. 这个问题对于Debian系的其他发行版 ...

  5. Eclipse文本编码格式修改为UTF-8 的方法

    整理自网络,亲测可用,记录一下,方便下次查. 一般Java文件编码格式是UTF-8的.以下以默认GBK改为UTF-8为例. 1.改变整个工作空间的编码格式,这样以后新建的文件也是新设置的编码格式. e ...

  6. 使用JS实现博客搜索关键字高亮

    说明 最近博客添加了搜索功能,有个需求是要针对搜索结果中搜索关键字需要高亮显示. 以便用户可以更快速的挑选自己中意的文章. 原理就是在渲染列表数据中给含有关键字的文本标签添加自定义class,渲染完毕 ...

  7. 探秘C语言数组:解锁高效数据管理与多维空间编程技巧"

    欢迎大家来到贝蒂大讲堂 养成好习惯,先赞后看哦~ 所属专栏:C语言学习 贝蒂的主页:Betty's blog 引言 前面贝蒂给大家介绍了选择结构与循环结构,今天,贝蒂准备给大家介绍C语言中一个非常重要 ...

  8. [Android 逆向]旅行青蛙破解

    1. 旅行青蛙V1.0,4 apk 安装到手机,可以运行 2. jadx 打开apk 存在这两个dll ,说明是 unity开发的 3. 导出Assembly-CSharp.dll, 使用DnSpy ...

  9. RK3588开发笔记(二):基于方案商提供sdk搭建引入mpp和sdk的宿主机交叉编译Qt5.12.10环境

    前言   上一篇项目已经构建好了Qt,板子接入mipi屏幕也跑起来了,Qt也能正常运行了,现在需要接入定制开发的sdk,sdk中使用了硬解码等资源涉及到bsp的mpp,所以下一步就是引入mpp和sdk ...

  10. 【系统选型】OA需求分析,OA系统选型及各供应商对比。

    去年公司内部做OA信息化升级,需要更新换代一下OA系统,当时OA选型整理下来的资料分享一下. 需求调研整理后如下: 一共四个模块需要更新&升级 :  OA模块(包括行政) + 合同模块 + 费 ...