Vue2 - keep-alive 作用和原理

目录

  • 1,介绍和作用
  • 2,原理
  • 3,使用场景
    • 3.1,效果展示
    • 3.2,实现思路

1,介绍和作用

<!-- 非活跃的组件将会被缓存! -->
<keep-alive><component :is="activeComponent" />
</keep-alive>

1,是一个内部组件,用于缓存组件实例。在组件切换时,不用重新创建而是使用缓存中的组件实例。

  • 可以避免创建组件的开销。
  • 可以保留组件状态

2,有3个属性:

  • includeexclude 属性,可以控制哪些组件进入缓存。
  • max 属性可以设置最大缓存数,当缓存的实例超过该数时,vue会移除最久没有使用的组件缓存。
<!-- 以英文逗号分隔的字符串 -->
<keep-alive include="Comp1,Comp2"><component :is="view" />
</keep-alive>
<!-- 数组 -->
<keep-alive :include="['Comp1', 'Comp2']"><component :is="view" />
</keep-alive>

3,受 keep-alive 影响,内部所有嵌套的组件都有2个生命周期函数。activateddeactivated。第1次 activated 是在 mounted 之后。

4,当嵌套组件是 <router-view> 时,缓存的是路由对应的组件。

因为 <router-view> 是函数式组件,只有一个目的,生成虚拟DOM。它没有状态,不生成实例。有穿透的效果。

<keep-alive><router-view></router-view>
</keep-alive>

2,原理

源码

keep-alive 在内部维护了一个缓存对象和 keys 数组:

// keep-alive 组件的生命周期函数
created () {this.cache = Object.create(null)this.keys = []
}
  • keys 数组记录当前缓存组件的 key,如果组件没有指定,则会自动为组件生成唯一的 key

  • cache 对象以 key 为键,vnode 为值,来缓存组件对应的虚拟 DOM。

keep-alive 组件的 render 函数中,大致逻辑:

判断当前渲染的 vnode 是否有对应的缓存,有则从缓存中读取对应组件实例,没有则将其缓存。当缓存数量 > max 时,会移除掉 keys 数组的第1个元素。

// 更新逻辑其实在 update 函数中,这里结合在一起容易理解。
render(){const slot = this.$slots.default; // 获取默认插槽const vnode = getFirstComponentChild(slot); // 得到插槽中的第一个组件的 vnodeconst name = getComponentName(vnode.componentOptions); // 获取组件名字const { cache, keys } = this; // 获取当前的缓存对象和key数组const key = ...; // 获取组件的key值,若没有,会按照规则自动生成if (cache[key]) {// 有缓存// 关键:重用组件实例vnode.componentInstance = cache[key].componentInstanceremove(keys, key); // 删除key// 将 key加入到数组末尾,这样是为了保证最近使用的组件在数组中靠后,反之靠前keys.push(key); } else {// 无缓存,则进行缓存cache[key] = vnodekeys.push(key)if (this.max && keys.length > parseInt(this.max)) {// 超过最大缓存数量,移除第一个key对应的缓存pruneCacheEntry(cache, keys[0], keys, this._vnode)}}return vnode || (slot && slot[0])
}

注意到,render() 返回的就是插槽中的第一个组件的 vnode。所以页面上显示的也就是这个子组件。

3,使用场景

在后台管理系统中比较常见,比如有2种情况就会用到:

  • 侧边栏的菜单,一般对应的是路由。切换页面(路由)时想保留之前的页面信息。
  • 列表页进详情页时,想保留列表页信息,因为列表可能是通过输入框等多个过滤条件得到的,如果从详情页返回列表页再次操作会比较繁琐。

这2种情况,都可以做成 tab 选项卡。

3.1,效果展示

在这里插入图片描述

3.2,实现思路

首先维护一个【tab选项卡】的状态,比如放到 Vuex 中。不放到组件内部,是因为不好使用,因为可能不止侧边栏会添加 tab,其他地方可能也会添加页面到 tab 选项卡。

export default new Vuex.Store({modules: {tabs: {namespaced: true,state: {pageNames: [] // 选项卡的页面},mutations: {addPage(state, newPageName) {if (!state.pageNames.includes(newPageName)) {state.pageNames.push(newPageName)}},removePage(state, pageName) {const index = state.pageNames.indexOf(pageName)if (index >= 0) {state.pageNames.splice(index, 1)}}}}}
})

其他的看代码就一目了然了:(省略了CSS)

<template><div><!-- 固定在页面左侧 --><div><h1>侧边栏</h1><ul><router-linkv-for="item in $router.options.routes":key="item.path"tag="li":to="{ name: item.name }"active-class="blue"><span>{{ item.name }}</span><button @click="handleAddPage(item.name)">+</button></router-link></ul></div><!-- 页面内容区域 --><div><!-- 固定在页面顶部,左侧和侧边栏对齐 --><div v-if="$store.state.tabs.pageNames.length"><span>tab选项卡:</span><ul><router-linkv-for="pageName in $store.state.tabs.pageNames":key="pageName"tag="li"active-class="green":to="{ name: pageName }"><span>{{ pageName }}</span><button @click="handleRemovePage(pageName)">x</button></router-link></ul></div><!-- 页面内容展示区域 --><keep-alive :include="$store.state.tabs.pageNames"><router-view></router-view></keep-alive></div></div>
</template><script>
export default {methods: {handleAddPage(pageName) {this.$store.commit('tabs/addPage', pageName)},handleRemovePage(pageName) {this.$store.commit('tabs/removePage', pageName)}}
}
</script>

以上。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Tomcat] [从安装到关闭] MAC部署方式

安装Tomcat 官网下载&#xff1a;Apache Tomcat - Apache Tomcat 9 Software Downloads 配置Tomcat 1、输入cd空格&#xff0c;打开Tomca目录&#xff0c;把bin文件夹直接拖拉到终端 2、授权bin目录下的所有操作&#xff1a;终端输入[sudo chmod 755 *.sh]&#xff0c;回车 …

JS进阶-解构赋值(一)

扩展&#xff1a;解构赋值时Js特有的一种处理数据的方式&#xff0c;在Java中没有处理数据的方式 知识引入&#xff1a; 思考&#xff1a;在js中&#xff0c;在没有学习解构赋值之前&#xff0c;我们是如何获取数组的内容的&#xff1f; 以上要么不好记忆&#xff0c;要么书写麻…

防御实验:(部分)

步骤一&#xff1a;了解前提&#xff1a; 1.1 题目要求&#xff1a; 需求一&#xff1a;DMZ区存在两台服务器&#xff0c;现在要求生产区的设备仅能在办公时间&#xff08;9&#xff1a;00 - 18&#xff1a;00&#xff09;访问&#xff0c;办公区的设备全天都可以访问。 需求二…

Kubernetes(K8S)各种攻击方法

1. 准备工作 1.1. metarget使用 项目地址(教程):https://github.com/Metarget/metarget/blob/master/README-zh.md 注意:推荐在Ubuntu 18.04(推荐)安装。 1.1.1. 安装metarget git clone https://github.com/Metarget/metarget.git cd metarget/ sudo apt install pyt…

Linux命令大全

文章目录 目录操作与文件管理系统信息与管理软件包管理和系统维护压缩与解压缩网络与通信辅助工具与信息获取文本处理与搜索时间与日期操作网络连接与通信&#xff08;补充&#xff09;链接管理磁盘与存储管理环境变量与路径设置用户和组管理查看系统信息 当然&#xff0c;以下…

(菜鸟自学)漏洞利用——MS11-080

&#xff08;菜鸟自学&#xff09;漏洞利用——MS11-080 漏洞简介利用漏洞对系统进行提权查看漏洞利用代码和工具将py脚本转换为exe程序渗透攻击验证 漏洞简介 MS11-080 是指微软于 2011 年发布的一个安全公告&#xff08;MS11-080&#xff09;&#xff0c;其中包含了关于 Win…

MySQL基础(一)

学习数据库的目的&#xff1a; 实现数据持久化到本地。使用完整的管理系统统一管理&#xff0c;可以实现结构化查询&#xff0c;方便管理。 一、数据库概述 数据库&#xff08;DataBase&#xff09; 为了方便数据的存储和管理&#xff0c;它将数据按照特定的 规则存储在磁盘…

关于axios给后端发送数据的问题

这里需要用的插件&#xff1a;qs.js&#xff0c;是前端给后端发送的数组&#xff0c;需要序列化所以要用到这个插件&#xff0c;这里就提取连接在这里&#xff0c;需要的自提&#xff0c;需要导如进来&#xff0c;别忘记了 链接&#xff1a;https://pan.baidu.com/s/1qyD8v9wfd…

爬虫笔记(二):实战58二手房

第一&#xff1a;给大家推荐一个爬虫的网课哈&#xff0c;码起来 第二&#xff1a;今夜主题&#xff1a;通过xpath爬取58二手房的title信息&#xff0c;也就是标红的位置~ 第三&#xff1a;先分析一波title所在的位置 打开按下f12打开抓包工具&#xff0c;即可看到网站的源码…

burp靶场--WebSockets安全漏洞

burp靶场–WebSockets安全漏洞 https://portswigger.net/web-security/websockets/what-are-websockets ### 什么是 WebSocket&#xff1f; WebSocket是一种通过 HTTP 发起的双向、全双工通信协议。它们通常在现代 Web 应用程序中用于流数据和其他异步流量。 在本节中&#x…

开始读 Oracle PL/SQL Programming 第6版

最近觉得PL/SQL越来越重要&#xff0c;因为这本书早就在待读列表中&#xff0c;因此决定系统的学一下。 2024年1月24日晚开始读。 在亚马逊上的评价还不错&#xff1a; 本书的第一作者是Steven Feuerstein&#xff0c;是Oracle资深的Developer Advocate。 本书的示例代码可…

「一本通 3.6 例 1」分离的路径

题目描述 为了从 F F F 个草场中的一个走到另一个&#xff0c;贝茜和她的同伴们不得不路过一些她们讨厌的可怕的树。奶牛们已经厌倦了被迫走某一条路&#xff0c;所以她们想建一些新路&#xff0c;使每一对草场之间都会至少有两条相互分离的路径&#xff0c;这样她们就有多一…

工程项目管理软件系统

工程项目管理软件系统单机版永久免费使用&#xff0c;无录入数量限制&#xff0c;无打印限制&#xff0c;无时间限制 1、产品概述 专业项目管理软件,业务流程清晰&#xff0c;操作简单&#xff0c;软件速度快; 围绕项目的(任务、进度、出库、入库、借用、人工、合同等)进行管理…

Zookeeper架构系列——集群模式

背景 架构图 集群模式详解 客户端连接到单个ZooKeeper服务器。客户端维护一个TCP连接&#xff0c;通过该连接发送请求、获取响应、获取监视事件和发送检测信号。如果与服务器的TCP连接中断&#xff0c;客户端将连接到其他服务器。 订购了ZooKeeper。ZooKeeper在每次更新时都…

数学建模常见算法的通俗理解(3)

11 Logistic模型&#xff08;计算是/否的概率&#xff09; 11.1 粗浅理解 我们有m张图片&#xff0c;并且获取了这些图片的特征向量的矩阵&#xff0c;我们需要判断这些图片中是否满足我们某个要求&#xff0c;如是否含有猫&#x1f431;这种动物。那么此时我们的每张图片传…

[HTML]Web前端开发技术12(HTML5、CSS3、JavaScript )——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

Word中插入公式并引用

1、如何插入公式 在word中,键入快捷键 “alt” + “=”,即可快速插入一个公式,并立即编辑。 2、利用表格框住公式 新建一个 1 行 3 列的表格,总宽度为页面宽度,第一个单元格和最后一个单元格都保持在 2.25cm,中间尽可能长。我设置的这个数值比较合理。 记住,要把表格…

ChromeDriver谷歌驱动最新版安装120/121/122

chromeDriver最新版本下载 最新驱动 https://googlechromelabs.github.io/chrome-for-testing/参考&#xff1a; https://blog.csdn.net/m0_57382185/article/details/134007615

【STM32】STM32学习笔记-W25Q64简介(37)

00. 目录 文章目录 00. 目录01. SPI简介02. W25Q64简介03. 硬件电路04. W25Q64框图05. Flash操作注意事项06. 预留07. 附录 01. SPI简介 在大容量产品和互联型产品上&#xff0c;SPI接口可以配置为支持SPI协议或者支持I 2 S音频协议。SPI接口默认工作在SPI方式&#xff0c;可以…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 1月25日,星期四

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年1月25日 星期四 农历腊月十五 1、 央行&#xff1a;2月5日下调存款准备金率0.5个百分点&#xff0c;1月25日下调支农支小再贷款、再贴现利率0.25个百分点&#xff0c;将向市场提供长期流动性1万亿元。 2、 人社部&#xf…