记录--Vue的缓存组件 | 详解KeepAlive
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
前言
一. 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,用于展示当前的计数值。同时,我们还绑定了三个自定义事件 increment、decrement 和 reset,用于响应计数器的操作。
当我们点击增加或减少按钮时,Counter 组件的 count 属性会发生变化,但由于它被包裹在 keep-alive 组件中,所以实际上并没有被销毁。当我们再次渲染 Counter 组件时,它会从缓存中获取到之前的实例,并将其重新挂载到 DOM 上,这样就能够保留之前的状态。 在上面的例子中,我们可以看到在 keep-alive 组件中只包含了一个 Counter 组件。但是,在实际应用中,我们可能需要缓存多个不同的组件,这时我们可以通过 include 和 exclude 属性来指定要缓存或排除的组件。
例如,我们可以修改上面的例子,将 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()方法强制重新渲染组件外,还可以使用include和exclude属性来控制哪些组件应该被缓存或不被缓存。当我们需要更新一个被缓存的组件时,可以将它从缓存中排除,并在需要更新时再重新包含到缓存中。这样可以避免无谓的重复渲染,提高应用的性能。
综上所述,我们可以通过使用 activated 和 deactivated 钩子函数、this.$forceUpdate() 方法以及 include 和 exclude 属性来控制被缓存的组件的刷新策略,以满足不同的需求。
五. keep-alive 页面缓存思路
功能需求描述:
- 页面前进刷新,后退不刷新
- 动态配置可缓存的页面
- 手动刷新已缓存的页面
实现思路:动态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的更多相关文章
- vue.js基础知识篇(6):组件详解
第11章:组件详解 组件是Vue.js最推崇也最强大的功能之一,核心目标是可重用性. 我们把组件代码按照template.style.script的拆分方式,放置到对应的.vue文件中. 1.注册 V ...
- Angular6 学习笔记——组件详解之组件通讯
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- Tomcat负载均衡、调优核心应用进阶学习笔记(一):tomcat文件目录、页面、架构组件详解、tomcat运行方式、组件介绍、tomcat管理
文章目录 tomcat文件目录 bin conf lib logs temp webapps work 页面 架构组件详解 tomcat运行方式 组件介绍 tomcat管理 tomcat文件目录 ➜ ...
- OpenStack的Swift组件详解
一:简介 一.背景 1. Swift 最初是由 Rackspace 公司开发的高可用分布式对象存储服务(Object Storage Service),并于 2010 年贡献给 OpenSt ...
- Redis for Windows(C#缓存)配置文件详解
Redis for Windows(C#缓存)配置文件详解 前言 在上一篇文章中主要介绍了Redis在Windows平台下的下载安装和简单使用http://www.cnblogs.com/aehy ...
- Angular6 学习笔记——组件详解之模板语法
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
- admin组件详解
admin组件详解 先根据admin组件启动流程复习下django项目启动至请求过来发生的事 1将admin组件注册进app 2django项目启动 3在运行到定制的admin时执行其下面的apps文 ...
- OpenStack各组件详解和通信流程
一.openstack由来 openstack最早由美国国家航空航天局NASA研发的Nova和Rackspace研发的swift组成.后来以apache许可证授权,旨在为公共及私有云平台建设.open ...
- Tomcat系列之服务器的安装与配置以及各组件详解
Tomcat系列之服务器的安装与配置以及各组件详解 大纲 一.前言 二.安装与配置Tomcat 三.Tomcat 目录的结构 四.Tomcat 配置文件 注,本文的测试的操作系统为CentOS 6.4 ...
- Logstash组件详解(input、codec、filter、output)
logstash组件详解 logstash的概念及特点. 概念:logstash是一个数据采集.加工处理以及传输(输出)的工具. 特点: - 所有类型的数据集中处理 - 不同模式和格式数据的正常化 - ...
随机推荐
- 【译】.NET 8 网络改进(一)
原文 | Máňa,Natalia Kondratyeva 翻译 | 郑子铭 随着新的 .NET 版本的发布,发布有关网络空间中新的有趣变化的博客文章已成为一种传统.今年,我们希望引入 HTTP 空间 ...
- CF1499
A 氵 B 如果 11 后出现了 00 就不行. C 枚举走几段. 横竖可以分开算. 一定是:除了费用最小的都是走长度 \(1\),费用最小的包揽剩下的. D \(c\cdot lcm(a,b)-d\ ...
- NC24734 [USACO 2010 Mar G]Great Cow Gathering
题目链接 题目 题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, ...
- 【OpenGL ES】正方形图片贴到圆形上
1 前言 纹理贴图 中介绍了将矩形图片贴到矩形模型上,本文将介绍:在不裁剪图片的情况下,将正方形的图片贴到圆形模型上. 思考:实数区间 [0, 1] 与 [0, 2] 的元素可以建立一一映射关 ...
- Spring Boot图书管理系统项目实战-10.借还统计
导航: pre: 9.归还图书 next:11.检索图书 只挑重点的讲,具体的请看项目源码. 1.项目源码 需要源码的朋友,请捐赠任意金额后留下邮箱发送:) 2.页面设计 2.1 bookStat. ...
- Redis集群单机环境搭建
概述 目标:在单台物理机上搭建3主3从共6个节点的Redis集群. 版本:Redis 6.2.4 系统:Ubuntu 18.04 Desktop(IP地址:192.168.100.247) 准备工作 ...
- 一次kafka消息丢失问题处理
背景&现象 生产微服务架构环境,kafka消息消费服务架构如下: 当服务B接口出现宕机或者B接口调用超时,kafka消息消费端服务A出现异常,异常发生后未执行手动提交offset操作.待服务B ...
- 【Azure 应用服务】App Service for Linux 环境中为Tomcat页面修改默认的Azure 404页面
问题描述 在App Service Linux环境中,如部署Tomcat 应用后,如果访问的页面找不到,应用会返回一个由Azure生成的404页面,那么是否可以修改它呢? PS: 如果是App Ser ...
- 图数据库|Nebula Graph v3.1.0 性能报告
本文首发于 Nebula Graph Community 公众号 本文系 Nebula Graph 发行版 v3.1.0 的性能测试报告. 本文目录 测试环境 测试数据 关于 LDBC-SNB 测试说 ...
- 从零开始学Spring Boot系列-集成MySQL
在Spring Boot中集成MySQL是为了让开发者能够轻松地与MySQL数据库进行交互.本篇文章将指导你如何在Spring Boot 3.2.3项目中使用Gradle来集成MySQL.在此之前,我 ...
