vue中的keep-alive是什么,有哪些使用场景,使用了什么原理,缓存后如何更新数据
<keep-alive> 是 Vue.js 提供的一个内置组件,用于缓存动态组件,避免频繁的销毁和重建。这在某些场景下可以显著提升性能,特别是在组件频繁切换的情况下。以下是对 keep-alive 的详细讲解,包括它的定义、使用场景、原理分析、如何使用以及缓存后如何更新数据。
什么是 keep-alive
<keep-alive> 是一个抽象组件,它不会渲染为一个 DOM 元素,也不会出现在父组件链中。它的主要作用是缓存动态组件的实例,而不是每次切换时销毁和重新创建它们。这对于提升性能和用户体验非常有用。
使用场景
<keep-alive> 适用于以下几种场景:
- 路由组件缓存:在单页应用中,用户在不同路由之间切换时,可以使用
keep-alive缓存路由组件,避免每次切换时重新加载和初始化组件。 - 标签页切换:在一个页面中有多标签页时,可以使用
keep-alive缓存每个标签页的内容,避免用户在切换标签页时重新加载数据。 - 列表项缓存:在列表组件中,当用户滚动时,可以使用
keep-alive缓存已经加载过的列表项,避免重复请求数据。
原理分析
<keep-alive> 的工作原理主要包括以下几个方面:
- 缓存机制:
<keep-alive>会维护一个缓存对象,存储被包裹的组件实例。当组件被激活时,从缓存中取出组件实例并复用;当组件被停用时,将组件实例存储到缓存中。 - 生命周期钩子:
<keep-alive>会注入两个额外的生命周期钩子:activated和deactivated。activated在组件被激活时调用,deactivated在组件被停用时调用。 - 条件缓存:通过
include和exclude属性,可以指定哪些组件需要被缓存,哪些组件不需要被缓存。
如何使用
在 Vue.js 中使用 <keep-alive> 非常简单。<keep-alive> 是一个内置组件,用于缓存动态组件,避免频繁的销毁和重建。
1. 基本用法
1.1 单个组件缓存
假设你有一个组件 MyComponent,你希望在切换时缓存它,可以这样做:
<template><div><button @click="showComponent = !showComponent">Toggle Component</button><keep-alive><MyComponent v-if="showComponent" /></keep-alive></div>
</template><script setup>
import { ref } from 'vue'
import MyComponent from './MyComponent.vue'const showComponent = ref(true)
</script>
在这个例子中,MyComponent 会在 showComponent 为 true 时显示,并且会被 keep-alive 缓存。当 showComponent 切换为 false 时,MyComponent 不会被销毁,而是被缓存起来。再次切换回 true 时,MyComponent 会从缓存中恢复,而不是重新创建。
1.2 动态组件缓存
你也可以使用 <keep-alive> 来缓存动态组件。假设你有多个组件 ComponentA 和 ComponentB,你希望在切换时缓存它们:
<template><div><button @click="currentComponent = 'ComponentA'">Show Component A</button><button @click="currentComponent = 'ComponentB'">Show Component B</button><keep-alive><component :is="currentComponent"></component></keep-alive></div>
</template><script setup>
import { ref } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'const currentComponent = ref('ComponentA')
</script>
在这个例子中,<component :is="currentComponent"> 会根据 currentComponent 的值动态切换组件,并且这些组件会被 keep-alive 缓存。
2. 控制缓存
2.1 include 和 exclude
你可以使用 include 和 exclude 属性来控制哪些组件需要被缓存,哪些组件不需要被缓存。这些属性可以接受字符串、正则表达式或数组。
<template><div><button @click="currentComponent = 'ComponentA'">Show Component A</button><button @click="currentComponent = 'ComponentB'">Show Component B</button><button @click="currentComponent = 'ComponentC'">Show Component C</button><keep-alive :include="['ComponentA', 'ComponentB']"><component :is="currentComponent"></component></keep-alive></div>
</template><script setup>
import { ref } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
import ComponentC from './ComponentC.vue'const currentComponent = ref('ComponentA')
</script>
在这个例子中,只有 ComponentA 和 ComponentB 会被缓存,ComponentC 不会被缓存。
3. 生命周期钩子
<keep-alive> 会注入两个额外的生命周期钩子:activated 和 deactivated。这些钩子分别在组件被激活和停用时调用。
<template><div><h1>{{ title }}</h1><p>{{ content }}</p></div>
</template><script setup>
import { ref, onActivated, onDeactivated } from 'vue'
import { fetchData } from './api'const title = ref('')
const content = ref('')onActivated(async () => {console.log('Component activated')// 检查数据是否需要更新if (shouldUpdateData()) {const data = await fetchData()title.value = data.titlecontent.value = data.content}
})onDeactivated(() => {console.log('Component deactivated')
})function shouldUpdateData() {// 根据实际情况判断是否需要更新数据return Math.random() > 0.5 // 示例:随机决定是否更新
}
</script>
4. 缓存后如何更新数据
4.1 使用 activated 钩子
在 activated 钩子中,可以检查数据是否需要更新,并重新获取数据。
<template><div><h1>{{ title }}</h1><p>{{ content }}</p></div>
</template><script setup>
import { ref, onActivated } from 'vue'
import { fetchData } from './api'const title = ref('')
const content = ref('')onActivated(async () => {// 检查数据是否需要更新if (shouldUpdateData()) {const data = await fetchData()title.value = data.titlecontent.value = data.content}
})function shouldUpdateData() {// 根据实际情况判断是否需要更新数据return Math.random() > 0.5 // 示例:随机决定是否更新
}
</script>
4.2 使用 watch 监听路由参数
如果组件是通过路由参数传递数据的,可以使用 watch 监听路由参数的变化,并在参数变化时更新数据。
<template><div><h1>{{ title }}</h1><p>{{ content }}</p></div>
</template><script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { fetchData } from './api'const route = useRoute()
const title = ref('')
const content = ref('')watch(() => route.params.id,async (newId) => {if (newId) {const data = await fetchData(newId)title.value = data.titlecontent.value = data.content}},{ immediate: true } // 立即执行一次
)
</script>
4.3 使用 key 属性
通过在 keep-alive 包裹的组件上添加 key 属性,可以强制组件重新渲染。当 key 发生变化时,keep-alive 会认为这是一个新的组件实例,从而重新创建和缓存。
<template><div><button @click="switchComponent">Switch Component</button><keep-alive><component :is="currentComponent" :key="currentKey"></component></keep-alive></div>
</template><script setup>
import { ref } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'const currentComponent = ref(ComponentA)
const currentKey = ref(1)const switchComponent = () => {currentComponent.value = currentComponent.value === ComponentA ? ComponentB : ComponentAcurrentKey.value += 1 // 改变 key,强制重新渲染
}
</script>
总结
<keep-alive> 是 Vue.js 中一个非常有用的组件,用于缓存动态组件,提升性能和用户体验。通过理解其基本用法、控制缓存、生命周期钩子以及如何在缓存后更新数据,可以更好地利用 <keep-alive> 来优化应用。
相关文章:
vue中的keep-alive是什么,有哪些使用场景,使用了什么原理,缓存后如何更新数据
<keep-alive> 是 Vue.js 提供的一个内置组件,用于缓存动态组件,避免频繁的销毁和重建。这在某些场景下可以显著提升性能,特别是在组件频繁切换的情况下。以下是对 keep-alive 的详细讲解,包括它的定义、使用场景、原理分析、…...
LeetCode105.从前序与中序遍历构造二叉树
题目要求 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 提示: 1 < preorder.length < 3000inorder.length preorder.length-3000 < pr…...
LeetCode654.最大二叉树
LeetCode刷题记录 文章目录 📜题目描述💡解题思路⌨C代码 📜题目描述 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值。 递归地在最大值 左边 的 子…...
C# 字段和属性
在 C# 中,字段和属性是定义类和结构体数据的两种方式。 字段用于直接存储数据,而属性提供了对字段的封装和访问控制。 1. 字段(Fields) 定义 字段是类或结构体中用于存储数据的变量。字段可以是任何数据类型,包括基…...
【leetcode】N皇后 回溯法c++
目录 51.N皇后 52.N皇后II 51.N皇后 51. N 皇后 - 力扣(LeetCode) 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间…...
Ubuntu 系统端口查询与管理详细分析
目录 前言1. 查询端口占用情况2. 释放占用的端口3. 修改应用程序的端口 前言 Window的端口被占用,类似的知识点:重装mysql时3306端口被占用解决方法 事情起因是宝塔的CPU负载过大,重启服务进程之后还是爆,后续发现是端口被占用&…...
Unity中使用StartCoroutine协程和Lerp方法,使GameObject缓慢移动
移动方法(传入需要移动的instance和目标位置) public Transform targetPosition; //目标位置 Vector3 target targetPosition.position;private IEnumerator MoveTowardsTarget(GameObject instance, Vector3 target){// 缓慢移动到目标的方法Vector3 …...
C++根据特定字符截取字符串
前言 在 C 中,如果根据特定字符进行字符串的截取,可以使用 std::string 类的成员函数 find() 来查找字符的位置,然后使用 substr() 来截取字符串。以下是一个示例,展示了如何根据指定字符截取字符串。 示例 #include <iostr…...
【How AI Works】读书笔记3 出发吧! AI纵览 第二部分
目录 1.说明 2.第二部分(P9~P10) 机器学习算法总结(监督学习) 3.单词 4.专业术语 1.说明 书全名:How AI Works From Sorcery to Science 作者 Ronald T.Kneusel 2.第二部分(P9~P10) 总结机器学习算法 作者把机器学习的过程比喻成输入-->黑盒-->输出 这里的标签可…...
No Module named pytorchvideo.losses问题解决
问题描述 最近在跑X3D的源码时发现,在conda powershell prompt中安装了pytorchvideo,但是仍然报错:No Module named pytorchvideo.losses 解决方案: 直接去https://gitcode.com/gh_mirrors/py/pytorchvideo/overview?utm_sour…...
Mac终端字体高亮、提示插件
一、安装配置“oh my zsh” 1.1 安装brew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 按照步骤安装即可,安装完成查看版本 brew -v 1.2 安装zsh brew install zsh 安装完成后查看版本 zsh --version 1.3 …...
Flowable 构建后端服务(后端以及数据库搭建) Flowable Modeler 设计器搭建(前端)
案例地址:xupengboo-flowable-example Flowable 构建后端服务(后端以及数据库搭建) 以 Spring Boot 项目为例: 引入 Flowable 必要依赖。 <!-- flowable 依赖 --> <dependency><groupId>org.flowable</gr…...
[Java]微服务拆分
导入项目 本篇及后续的微服务学习都是基于Centos7系统下的Docker部署,因此需要准备: Centos7的环境SSH客户端安装好Docker会使用Docker 之前的学习, 导致虚拟机中存在黑马商城项目以及mysql数据库, 为了保持一致, 需要删除 cd /rootdocker compose down 安装mysq…...
JavaScript逆向爬虫教程-------基础篇之JavaScript混淆原理
目录 一、常量的混淆原理1.1 对象属性的两种访问方式1.2 十六进制字符串1.3 Unicode字符串1.4 字符串的ASCII码混淆1.5 字符串常量加密1.6 数值常量加密二、增加 JS 逆向者的工作量2.1 数组混淆2.2 数组乱序2.3 花指令2.4 jsfuck三、代码执行流程的防护原理3.1 流程平坦化3.2 …...
qt移植到讯为rk3568,包含一些错误总结
qt移植到arm报错动态库找不到 error while loading shared libraries: libAlterManager.so.1: cannot open shared object file: No such file or directory 通过设置环境变量 LD_LIBRARY_PATH就行了。 LD_LIBRARY_PATH是一个用于指定动态链接器在运行时搜索共享库的路径的环…...
使用阿里云快速搭建 DataLight 平台
使用阿里云快速搭建 DataLight 平台 本篇文章由用户 “闫哥大数据” 分享,B 站账号:https://space.bilibili.com/357944741?spm_id_from333.999.0.0 注意:因每个人操作顺序可能略有区别,整个部署流程如果出现出入,以…...
ubuntu设置自启动
1. 把要启动的程序或者脚本(比如A.sh、A1)放在 /usr/sbin 目录中。比如我的 A.sh 只是启动 A1 程序: #!/bin/bash/usr/sbin/A1echo "A1 finish!!!" 需要注意的是,脚本和程序都要有可执行的权限才行 2. 在 /etc/systemd/system 目录中创建 .…...
Paddle分布式训练报NCCL错
应该是没有装NCCL,但是通过NVIDIA官网方式用apt安装报错,说nccl签名有问题 打开官网查找对应版本的nccl:https://developer.nvidia.com/nccl/nccl-legacy-downloads 这里不下载local Ubuntu选项,下载O/S agnostic local install…...
PD3.1快充对我们到底有没有必要?
在科技飞速发展的今天,各种智能设备和电子产品已经渗透到了我们生活的方方面面。随之而来的,是对充电速度和效率的不断追求。正是在这样的背景下,USB联盟于2021年6月发布了最新的快充协议——PD3.1。那么,PD3.1快充协议对我们到底…...
Android OpenGL ES详解——立方体贴图
目录 一、概念 二、如何使用 1、创建立方体贴图 2、生成纹理 3、设置纹理环绕和过滤方式 4、激活和绑定立方体贴图 三、应用举例——天空盒 1、概念 2、加载天空盒 3、显示天空盒 4、优化 四、应用举例——环境映射:反射 五、应用举例——环境映射:折射 六、应用…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
