在vue中对keep-alive的理解,它是如何实现的,具体缓存的是什么?
对keep-alive的理解,它是如何实现的,具体缓存的是什么?
- (1)keep-alive有以下三个属性:
- 注意:keep-alive 包裹动态组件时,会缓存不活动的组件实例。
- 主要流程
- (2)keep-alive 的实现
- render函数
- (3)keep-alive 本身的创建过程和 patch 过程
- (4)LRU (least recently used)缓存策略
如果需要在组件切换的时候,保存一些组件的状态防止多次渲染,就可以使用 keep-alive 组件包裹需要保存的组件。
(1)keep-alive有以下三个属性:
include 字符串或正则表达式,只有名称匹配的组件会被匹配;
exclude 字符串或正则表达式,任何名称匹配的组件都不会被缓存;
max 数字,最多可以缓存多少组件实例。
注意:keep-alive 包裹动态组件时,会缓存不活动的组件实例。
主要流程
判断组件 name ,不在 include 或者在 exclude 中,直接返回 vnode,说明该组件不被缓存。
获取组件实例 key ,如果有获取实例的 key,否则重新生成。
key生成规则,cid +“∶∶”+ tag ,仅靠cid是不够的,因为相同的构造函数可以注册为不同的本地组件。
如果缓存对象内存在,则直接从缓存对象中获取组件实例给 vnode ,不存在则添加到缓存对象中。 5.最大缓存数量,当缓存组件数量超过 max 值时,清除 keys 数组内第一个组件。
(2)keep-alive 的实现
const patternTypes: Array<Function> = [String, RegExp, Array] // 接收:字符串,正则,数组export default {name: 'keep-alive',abstract: true, // 抽象组件,是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。props: {include: patternTypes, // 匹配的组件,缓存exclude: patternTypes, // 不去匹配的组件,不缓存max: [String, Number], // 缓存组件的最大实例数量, 由于缓存的是组件实例(vnode),数量过多的时候,会占用过多的内存,可以用max指定上限},created() {// 用于初始化缓存虚拟DOM数组和vnode的keythis.cache = Object.create(null)this.keys = []},destroyed() {// 销毁缓存cache的组件实例for (const key in this.cache) {pruneCacheEntry(this.cache, key, this.keys)}},mounted() {// prune 削减精简[v.]// 去监控include和exclude的改变,根据最新的include和exclude的内容,来实时削减缓存的组件的内容this.$watch('include', (val) => {pruneCache(this, (name) => matches(val, name))})this.$watch('exclude', (val) => {pruneCache(this, (name) => !matches(val, name))})},
}
render函数
1.会在 keep-alive 组件内部去写自己的内容,所以可以去获取默认 slot 的内容,然后根据这个去获取组件
2.keep-alive 只对第一个组件有效,所以获取第一个子组件。
3.和 keep-alive 搭配使用的一般有:动态组件 和router-view
render () {//function getFirstComponentChild (children: ?Array<VNode>): ?VNode {if (Array.isArray(children)) {for (let i = 0; i < children.length; i++) {const c = children[i]if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {return c}}}}const slot = this.$slots.default // 获取默认插槽const vnode: VNode = getFirstComponentChild(slot)// 获取第一个子组件const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions // 组件参数if (componentOptions) { // 是否有组件参数// check patternconst name: ?string = getComponentName(componentOptions) // 获取组件名const { include, exclude } = thisif (// not included(include && (!name || !matches(include, name))) ||// excluded(exclude && name && matches(exclude, name))) {// 如果不匹配当前组件的名字和include以及exclude// 那么直接返回组件的实例return vnode}const { cache, keys } = this// 获取这个组件的keyconst key: ?string = vnode.key == null// same constructor may get registered as different local components// so cid alone is not enough (#3269)? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : ''): vnode.keyif (cache[key]) {// LRU缓存策略执行vnode.componentInstance = cache[key].componentInstance // 组件初次渲染的时候componentInstance为undefined// make current key freshestremove(keys, key)keys.push(key)// 根据LRU缓存策略执行,将key从原来的位置移除,然后将这个key值放到最后面} else {// 在缓存列表里面没有的话,则加入,同时判断当前加入之后,是否超过了max所设定的范围,如果是,则去除// 使用时间间隔最长的一个cache[key] = vnodekeys.push(key)// prune oldest entryif (this.max && keys.length > parseInt(this.max)) {pruneCacheEntry(cache, keys[0], keys, this._vnode)}}// 将组件的keepAlive属性设置为truevnode.data.keepAlive = true // 作用:判断是否要执行组件的created、mounted生命周期函数}return vnode || (slot && slot[0])
}
keep-alive 具体是通过 cache 数组缓存所有组件的 vnode 实例。当 cache 内原有组件被使用时会将该组件 key 从 keys 数组中删除,然后 push 到 keys数组最后,以便清除最不常用组件。
实现步骤:
1.获取 keep-alive 下第一个子组件的实例对象,通过他去获取这个组件的组件名
2.通过当前组件名去匹配原来 include 和 exclude,判断当前组件是否需要缓存,不3.需要缓存,直接返回当前组件的实例vNode需要缓存,判断他当前是否在缓存数组里面:
(1)存在,则将他原来位置上的 key 给移除,同时将这个组件的 key 放到数组最后面(LRU)
(2)不存在,将组件 key 放入数组,然后判断当前 key数组是否超过 max 所设置的范围,超过,那么削减未使用时间最长的一个组件的 key
4.最后将这个组件的 keepAlive 设置为 true
(3)keep-alive 本身的创建过程和 patch 过程
缓存渲染的时候,会根据 vnode.componentInstance(首次渲染 vnode.componentInstance 为 undefined) 和 keepAlive 属性判断不会执行组件的 created、mounted 等钩子函数,而是对缓存的组件执行 patch 过程∶ 直接把缓存的 DOM 对象直接插入到目标元素中,完成了数据更新的情况下的渲染过程。
组件的首次渲染∶判断组件的 abstract 属性,才往父组件里面挂载 DOM
// core/instance/lifecycle
function initLifecycle (vm: Component) {const options = vm.$options// locate first non-abstract parentlet parent = options.parentif (parent && !options.abstract) { // 判断组件的abstract属性,才往父组件里面挂载DOMwhile (parent.$options.abstract && parent.$parent) {parent = parent.$parent}parent.$children.push(vm)}vm.$parent = parentvm.$root = parent ? parent.$root : vmvm.$children = []vm.$refs = {}vm._watcher = nullvm._inactive = nullvm._directInactive = falsevm._isMounted = falsevm._isDestroyed = falsevm._isBeingDestroyed = false
}
判断当前 keepAlive 和 componentInstance 是否存在来判断是否要执行组件 prepatch 还是执行创建 componentlnstance
// core/vdom/create-component
init (vnode: VNodeWithData, hydrating: boolean): ?boolean {if (vnode.componentInstance &&!vnode.componentInstance._isDestroyed &&vnode.data.keepAlive) { // componentInstance在初次是undefined!!!// kept-alive components, treat as a patchconst mountedNode: any = vnode // work around flowcomponentVNodeHooks.prepatch(mountedNode, mountedNode) // prepatch函数执行的是组件更新的过程} else {const child = vnode.componentInstance = createComponentInstanceForVnode(vnode,activeInstance)child.$mount(hydrating ? vnode.elm : undefined, hydrating)}},
prepatch 操作就不会在执行组件的 mounted 和 created 生命周期函数,而是直接将 DOM 插入
(4)LRU (least recently used)缓存策略
LRU 缓存策略∶ 从内存中找出最久未使用的数据并置换新的数据。
LRU(Least rencently used)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是 “如果数据最近被访问过,那么将来被访问的几率也更高”。 最常见的实现是使用一个链表保存缓存数据,详细算法实现如下∶
1.新数据插入到链表头部
2.每当缓存命中(即缓存数据被访问),则将数据移到链表头部
3.链表满的时候,将链表尾部的数据丢弃。
相关文章:
在vue中对keep-alive的理解,它是如何实现的,具体缓存的是什么?
对keep-alive的理解,它是如何实现的,具体缓存的是什么? (1)keep-alive有以下三个属性:注意:keep-alive 包裹动态组件时,会缓存不活动的组件实例。主要流程 (2)…...
章节一、认识three.js与开发环境学习笔记01;
一、如何学习WEB可视化3D技术与课程内容演示; 1、项目案例: 政府有大量的新基建的项目:如数字孪生、智慧城市、智慧园区、智慧工厂、智慧消防等等都涉及了3d的可视化技术; 2、如何系统的学号WEB 3D可视化技术? three…...
QT摄像头采集
主界面为显示框,两个下拉框,一个是所有相机,一个是相机支持的分辨率 系统根据UI界面自动生成的部分不再描述,以下为其他部分源码 widget.h #include <QWidget> #include <QMouseEvent> class QCamera; class QCamer…...
C语言第三十四弹---动态内存管理(下)
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 动态内存管理 1、动态内存经典笔试题分析 1.1、题目1 1.2、题目2 1.3、题目3 1.4、题目4 2、柔性数组 2.1、柔性数组的特点 2.2、柔性数组的使用 2.3、…...
PDN分析及应用系列二-简单5V电源分配-Altium Designer仿真分析-AD
PDN分析及应用系列二 —— 案例1:简单5V电源分配 预模拟DC网络识别 当最初为PCB设计打开PDN分析仪时,它将尝试根据公共电源网络命名法从设计中识别所有直流电源网络。 正确的DC网络识别对于获得最准确的模拟结果非常重要。 在示例项目中已经识别出主DC网络以简化该过程。 …...
Vue开发实例(一)Vue环境搭建第一个项目
Vue环境搭建&第一个项目 一、环境搭建二、安装Vue脚手架三、创建Vue项目 一、环境搭建 下载方式从官网下载:http://nodejs.cn/download/ 建议下载v12.16.0版本以上的,因为版本低无法创建Vue的脚手架 检验是否安装成功 配置环境变量 新增NODE_HOME&…...
将SpringBoot项目改造成solon项目
solon项目介绍 官网 Java “生态型”应用开发框架:更快、更小、更简单。 启动快 5 ~ 10 倍;并发高 2~ 3 倍; 内存省 1/3 ~ 1/2;打包缩到 1/2 ~ 1/10;同时支持 java8, java11, java17, java21&a…...
更详细的软件测试理论基础:流程,开发、测试模型,测试分类,测试用例及其设计方法,缺陷
文章目录 一、测试流程二、开发模型1、 瀑布模型2、增量模型3、快速模型4、其他 三、测试模型1、V模型2、W模型 四、测试分类五、测试用例 test case六、测试用例设计方法1、等价类划分法2、边界值分析法3、因果图法4、判定表法5、正交法6、场景法7、流程分析法8、错误推测法方…...
input css padding
这样控件会跑出外套控件在HTML JSP里面是经常出现的。但有些外国adobe的as控件不存在这种情况,这是因为内层控件定义的时候不能超出外层控件的范围。 修改下:去掉原来css padding,然后加上宽度和高度...
如何打印 springboot 框架中 接收请求的日志
在 Spring Boot 框架中,您可以使用日志来记录接收请求和发送响应的详细信息。Spring Boot 默认使用 SLF4J(Simple Logging Facade for Java)作为日志抽象层,并支持多种日志实现,如 Logback、Log4j2 等。以下是一种常见…...
JVM的内存区域划分
JVM即Java虚拟机,是Java实现跨平台交互能力的核心,Java编译后的.class文件,就是通过虚拟机和操作系统进行交互的; 常见的虚拟机有:JVM、VMwave、Virtual Box,目前最主流使用的JVM是HotSpot VM;…...
YOLOv9有效改进|使用动态蛇形卷积Dynamic Snake Convolution
专栏介绍:YOLOv9改进系列 | 包含深度学习最新创新,主力高效涨点!!! 一、改进点介绍 使用ICCV2023中的动态蛇形卷积替换YOLOv9网络中的Conv模块。 二、Dynamic Snake Convolution模块详解 2.1 模块简介 应用场景&#x…...
设计模式学习笔记 - 设计原则 - 1.单一职责原则
前言 前面我们提到过 SOLID 原则,实际上 SOLID 由 5 个设计原则组成,分别是:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖反转原则。它们分别对应 SLOID 中的 S、O、L、I、D 这 5 个英文字母。 今天来学习下 SOLID 原则中的第…...
飞天使-学以致用-devops知识点4-SpringBoot项目CICD实现(实验失败,了解大概流程)
文章目录 代码准备创建jenkins 任务测试推送使用项目里面的jenkinsfile 进行升级操作 文字版本流程项目构建 代码准备 推送代码到gitlab 代码去叩叮狼教育找 k8s 创建jenkins 任务 创建一个k8s-cicd-demo 流水线任务 将jenkins 里面构建时候的地址还有token, 给到…...
使用HTML5画布(Canvas)模拟图层(Layers)效果
使用HTML5画布(Canvas)模拟图层(Layers)效果 在图形处理和计算机图形学中,图层(Layers)是指将图像分成不同的可独立编辑、组合和控制的部分的技术或概念。每个图层都可以包含不同的图形元素、效…...
违背祖训,微软骚操作强制用户更新至 Win 11 23H2
话说,大伙儿有让 Windows 操作系统一直保持最新版习惯吗? 根据以往惯例,Windows 系统更新是个比较玄学的存在,谁也不能保证随手更新后会不会出现什么奇葩 Bug。 因此对于不少同学来说,Windows 更新到一个稳定版本后&a…...
MISRA C++ 2023指南:您需要了解的一切
MISRA C 2023可以帮助使用现代C语言的组织开发安全关键型软件。使用新的MISRA标准,开发人员可以通过确保和记录其软件应用程序的MISRA合规性,满足IEC 6108或ISO 26262等功能安全标准给出的静态分析要求。 什么是MISRA C2023? 以便使用C17进行安全可靠…...
Vue:【亲测可用】父组件数组包对象,传给子组件对象,子组件修改属性(字段)后,父组件没有更新
场景:vue中父组件数组包对象,传给子组件对象,子组件修改属性(字段)后,父组件没有更新 代码: # 父组件 <div v-for"(object, name, index) in arr" :key"index"><…...
hbase学习十:客户端实现与Meta表解析
1、客户端实现 hbase社区的客户端一般是java客户端。 HBase也支持Shell交互式客户端。Shell客户端实质是用JRuby(用Java编写的Ruby解释器,方便Ruby脚本跑在JVM虚拟机上)脚本调用官方HBase客户端来实现的。因此,各种客户端的核心实现都在社区Java版本客户端上。 客户端访…...
《OpenScene: 3D Scene Understanding with Open Vocabularies》阅读笔记1
传统的3D场景理解方法依赖于带标签的3D数据集,用于训练一个模型以进行单一任务的监督学习。我们提出了OpenScene,一种替代方法,其中模型在CLIP特征空间中预测与文本和图像像素共同嵌入的3D场景点的密集特征。这种零样本方法实现了与任务无关的训练和开放词汇查询。例如,为了…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
高抗扰度汽车光耦合器的特性
晶台光电推出的125℃光耦合器系列产品(包括KL357NU、KL3H7U和KL817U),专为高温环境下的汽车应用设计,具备以下核心优势和技术特点: 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计,确保在…...
