Vue 2 与 Vue 3 中 keep-alive 组件的深入解析

news2024/11/25 10:28:06

更多内容前往个人网站:孔乙己大叔 

       在 Vue.js 的开发中,keep-alive 是一个非常重要的内置组件,它允许我们将组件状态或实例保持在内存中,避免重新渲染和重新创建组件,这对于需要频繁切换但内容较为复杂的组件场景非常有用,如标签页、列表项的详细视图等。Vue 2 和 Vue 3 在实现 keep-alive 组件时,虽然核心思想相似,但在具体实现上存在一些差异。本文将详细解析 Vue 2 和 Vue 3 中 keep-alive 组件的实现原理、代码差异以及各自的优势。

一、Vue 2 中的 keep-alive 实现

        在 Vue 2 中,keep-alive 组件是通过选项式 API(Options API)来定义的,它内部使用了一个对象(通常是一个 Object.create(null) 创建的空对象)来存储缓存的组件实例,同时用一个数组来维护这些缓存组件的键列表。这种实现方式在 Vue 2 的响应式系统和虚拟 DOM 框架下运作良好。

1. 核心功能实现

Vue 2 中的 keep-alive 组件主要实现了以下几个核心功能:

  • 缓存管理:使用对象字面量(Object.create(null))来避免原型链上的干扰,并作为缓存容器。
  • 键管理:使用一个数组来存储缓存组件的键,确保可以通过顺序来管理缓存的优先级。
  • 条件渲染:通过 render 函数来判断哪些组件需要被缓存,哪些不需要。
  • 缓存逻辑:根据组件的 key 或构造函数的 cid(Component ID)来判断缓存中是否已存在对应的组件实例,如果存在则复用,否则创建新实例并存入缓存。
  • 缓存限制:通过 max 属性来限制缓存的最大数量,当缓存数量超过限制时,会清理最早缓存的组件实例。
2. 示例代码解析

        以下是 Vue 2 中 keep-alive 组件的简化实现代码:

export default {  
  name: 'keep-alive',  
  props: {  
    include: [String, RegExp, Array],  
    exclude: [String, RegExp, Array],  
    max: [String, Number]  
  },  
  created() {  
    this.cache = Object.create(null);  
    this.keys = [];  
  },  
  render() {  
    const slot = this.$slots.default;  
    const vnode = getFirstComponentChild(slot);  
  
    if (vnode && vnode.componentOptions) {  
      // 省略 include/exclude 逻辑...  
  
      const key = vnode.key == null  
        ? vnode.componentOptions.Ctor.cid + (vnode.componentOptions.tag ? `::${vnode.componentOptions.tag}` : '')  
        : vnode.key;  
  
      if (this.cache[key]) {  
        vnode.componentInstance = this.cache[key].componentInstance;  
        // 更新键的顺序  
      } else {  
        this.cache[key] = vnode;  
        this.keys.push(key);  
        // 处理 max 属性逻辑...  
      }  
  
      vnode.data.keepAlive = true;  
    }  
  
    return vnode || (slot && slot[0]);  
  },  
  // 省略 pruneCacheEntry 和 pruneCache 等辅助函数...  
};
3. 优点与不足

优点

  • 实现了基本的缓存功能,提高了组件渲染性能。
  • 提供了 include 和 exclude 属性来灵活控制哪些组件需要被缓存。
  • 支持 max 属性来限制缓存大小,避免内存溢出。

不足

  • 使用对象字面量和数组来管理缓存和键列表,虽然简单但不够高效。
  • 响应式系统和虚拟 DOM 的处理相对原始,难以利用 Vue 3 的新特性。
二、Vue 3 中的 keep-alive 实现

Vue 3 在许多方面都进行了重构和优化,keep-alive 组件也不例外。Vue 3 使用了组合式 API(Composition API)和 Proxy 实现的响应式系统,以及更高效的虚拟 DOM 算法,这些变化也体现在了 keep-alive 的实现上。

1. 核心功能实现

Vue 3 中的 keep-alive 组件在核心功能上与 Vue 2 类似,但在实现细节上有所不同:

  • 缓存管理:使用 Map 数据结构来存储缓存的组件实例,这比 Vue 2 中的对象字面量更高效,因为 Map 保留了插入顺序,并且可以直接通过键来访问值。
  • 键管理:使用 Set 数据结构来存储缓存组件的键,Set 提供了更好的性能保证,特别是当需要快速判断某个键是否存在时。
  • 组合式 API:利用 Vue 3 的组合式 API(如 refwatchgetCurrentInstance 等)来增强组件的灵活性和可维护性。
  • 渲染函数:虽然 Vue 3 仍然支持选项式 API,但推荐使用组合式 API 来定义组件的逻辑。不过,keep-alive 组件的内部实现仍然使用了渲染函数来处理 DOM 的渲染逻辑。
2. 示例代码解析

以下是 Vue 3 中 keep-alive 组件的简化实现代码:

import { defineComponent, onMounted, onUnmounted, ref, watch, getCurrentInstance } from 'vue';  
  
const KeepAlive = defineComponent({  
  name: 'KeepAlive',  
  props: {  
    include: [String, RegExp, Array],  
    exclude: [String, RegExp, Array],  
    max: [String, Number]  
  },  
  setup(props, { slots }) {  
    const cache = new Map();  
    const keys = new Set();  
    let current = null;  
  
    // 省略 getComponentName、getFirstComponentChild 等辅助函数...  
  
    const instance = getCurrentInstance();  
    instance.ctx.activate = (vnode, container, anchor) => {  
      // 省略 vnode 激活逻辑...  
    };  
  
    instance.ctx.deactivate = (vnode) => {  
      // 省略 vnode 停用逻辑...  
    };  
  
    // 省略 pruneCacheEntry 和 pruneCache 等辅助函数...  
  
    // 返回 render 函数或 render 函数的返回值  
    return () => {  
      const slot = slots.default && slots.default();  
      const vnode = getFirstComponentChild(slot);  
  
      if (vnode && vnode.type && vnode.type.__isKeepAlive) {  
        // 省略 include/exclude 逻辑...  
  
        const key = vnode.key == null  
          ? vnode.type.__file + `::${vnode.type.name}`  
          : vnode.key;  
  
        if (cache.has(key)) {  
          vnode.component = cache.get(key).component;  
          // 更新键的顺序  
        } else {  
          cache.set(key, vnode);  
          keys.add(key);  
          // 处理 max 属性逻辑...  
        }  
  
        vnode.el = vnode.component.el;  
      }  
  
      return vnode || (slot && slot[0]);  
    };  
  }  
});  
  
export default KeepAlive;

注意:上述代码是一个高度简化的示例,主要用于说明 Vue 3 中 keep-alive 组件的实现思路。实际上,Vue 3 的 keep-alive 组件实现要复杂得多,涉及到更多的内部逻辑和性能优化。

3. 优点与不足

优点

  • 使用 Map 和 Set 数据结构来管理缓存和键列表,提高了性能。
  • 利用 Vue 3 的组合式 API 来增强组件的灵活性和可维护性。
  • 更好的支持 Vue 3 的响应式系统和虚拟 DOM 算法。

不足

  • 相对于 Vue 2,Vue 3 的 keep-alive 组件实现更为复杂,需要更深入地理解 Vue 3 的内部机制。
  • 迁移现有项目到 Vue 3 时,可能需要调整与 keep-alive 相关的代码。
三、Vue 2 与 Vue 3 中 keep-alive 的实现差异
1. 缓存管理机制
  • Vue 2:使用对象字面量和数组来管理缓存和键列表。
  • Vue 3:使用 Map 和 Set 数据结构来管理缓存和键列表,提高了性能。
2. 代码结构
  • Vue 2:使用选项式 API 定义组件,render 函数处理 DOM 渲染逻辑。
  • Vue 3:推荐使用组合式 API 定义组件逻辑,但 keep-alive 的内部实现仍然使用了渲染函数。
3. 响应式系统和虚拟 DOM
  • Vue 2:使用基于 Object.defineProperty 的响应式系统和虚拟 DOM 算法。
  • Vue 3:使用基于 Proxy 的响应式系统和更高效的虚拟 DOM 算法,提供了更好的性能和更多的优化空间。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在银河麒麟中快速查询网卡固件及驱动信息

如何在银河麒麟中快速查询网卡固件及驱动信息 1、第一步:找到网卡名称2、第二步:查询固件和驱动信息3、总结 💖The Begin💖点点关注,收藏不迷路💖 在银河麒麟服务器操作系统中,如何查询网卡固件…

统一NLP和目标检测的DETR(一)——self attention、encoder、decoder

主流目标检测算法劣势 YOLO系列,它基于anchor来做,少不了要用MNS,导致速度相对较慢。 但今天介绍一款DETR,基于VIT的目标检测算法。 那么我们需要先深入过一遍VIT。 Vision transform 1、传统RNN网络的问题 单向:只…

vue3集成sql语句编辑器

使用的是codemirror 安装 pnpm add codemirror vue-codemirror --savepnpm add codemirror/lang-sqlpnpm add codemirror/theme-one-dark使用 <template><codemirror v-model"configSql" placeholder"Code goes here..." ref"codemirrorR…

热力图科普:数据可视化的利器

hello大家好&#xff0c;俺是没事爱瞎捣鼓又分享欲爆棚的叶同学&#xff01;&#xff01;&#xff01; 日常闲扯 哎呀&#xff0c;第一天上完课&#xff0c;给俺的感觉是&#xff08;热和惊喜&#xff09;&#xff0c;热是真热&#xff0c;从出租屋走到教学楼给我整的汗流浃背…

十七、网络编程

文章目录 一、网络相关的概念二、InetAddresss类三、Socket3.1 基本介绍 四、TCP网络通信编程4.1 应用案例1(使用字节流)4.2 应用案例2(使用字节流)4.3 应用案例3(使用字符流)4.4 应用案例4&#xff08;TCPFileCopy&#xff09;4.5 netstat 指令4.6 TCP网络通讯不为人知的秘密 …

为啥一定要考HCIE安全?这4个理由你不得不看

大家都知道&#xff0c;网络安全越来越成为企业和个人关注的焦点。 随着网络攻击的日益复杂和频繁&#xff0c;对于具备高级网络安全技能的专业人才的需求也在不断增长。HCIE-Security认证&#xff0c;作为华为推出的顶级信息安全认证&#xff0c;正是满足这一需求的黄金标准。…

inflight 守恒化简

设 x 为 E bw / delay 效能&#xff0c;y 为 flow 在瓶颈处的实际分配带宽&#xff0c;r 为时延&#xff0c;inflt 守恒模型的方程组如下&#xff1a; I ( t ) ∑ i 0 n w i ( t ) I(t)\displaystyle\sum_{i0}^n w_i(t) I(t)i0∑n​wi​(t) d x d t y r − x \dfrac{dx}{dt…

论文速读|自然语言的最优控制合成:机遇与挑战

项目地址&#xff1a;Optimal Control Synthesis from Natural Language: Opportunities and Challenges 介绍了一种从自然语言自动生成最优控制器的框架&#xff0c;该框架主要包括以下几个步骤&#xff1a;首先&#xff0c;通过人类用户提供的初始文本和系统描述&#xff0c;…

苹果系统中如何安装Python和PyCharm

1、Python官网下载安装包 Python官网下载苹果版本的安装包。 2、PyCharm官网下载安装包 3、下载完毕后安装Python 我采用的是在Windows下下载安装包&#xff0c;然后移动硬盘挂接到MacOS的方式进行安装。 双击开始安装Python Python安装完毕 4、Python安装完毕后的测定 注意直…

【开源免费】基于SpringBoot+Vue.JS高校校园招聘服务系统(JAVA毕业设计)

本文项目编号 T 010 &#xff0c;文末自助获取源码 \color{red}{T010&#xff0c;文末自助获取源码} T010&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

Qt QPushButton 按钮添加数字气泡

使用场景 项目中&#xff0c;在某个按钮的右上角添加数字气泡是一个很常见的功能&#xff0c;可以用新建一个组合类来实现。不过这样比较麻烦&#xff0c;如果加气泡是后面的需求&#xff0c;可能改动的地方较多。 下面介绍2种比较简单&#xff0c;不需要改动按钮响应的方式。…

Web3社交新经济,与 SOEX 实现无缝交易的高级安全性

出于充分的理由&#xff0c;安全性是交易中至关重要的考虑因素。每个人都应该确保自己的资金在交易时是安全的。由于 &#xff33;&#xff2f;&#xff25;&#xff38; 充当您与交易所的最佳连接&#xff0c;因此必须强调的是&#xff0c;该系统不会引发任何安全问题。 &a…

央视曝光“硫超标”枸杞,记者直击加工现场:被熏到泪流不止

枸杞&#xff0c;这一自古以来便被誉为“药食同源”的珍贵食材&#xff0c;不仅承载着中华民族深厚的养生智慧&#xff0c;也广泛融入现代人的日常饮食与保健之中。 从食品、饮料到保健品&#xff0c;枸杞的身影无处不在&#xff0c;其独特的营养价值与药用价值深受消费者青睐。…

心电调试笔记

原理图设计 注意事项 引脚连接检查&#xff1a;确保每个元器件与芯片引脚连接正确是基础&#xff0c;错误的连接可能导致系统无法正常工作。未连接引脚标识&#xff1a;对于未使用的引脚&#xff0c;虽然不连接但应标识为非使用状态&#xff0c;以免混淆或引起误操作。测试点设…

【 html+css 绚丽Loading 】 000034 三元聚散盘

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

解锁MySQL数据库基础命令:从入门到精通的实战指南

作者简介&#xff1a;我是团团儿&#xff0c;是一名专注于云计算领域的专业创作者&#xff0c;感谢大家的关注 座右铭&#xff1a; 云端筑梦&#xff0c;数据为翼&#xff0c;探索无限可能&#xff0c;引领云计算新纪元 个人主页&#xff1a;团儿.-CSDN博客 前言&#xff1a;…

PLUTO: 推动基于模仿学习的自动驾驶规划的极限

PLUTO: Pushing the Limit of Imitation Learning-based Planning for Autonomous Driving PLUTO: 推动基于模仿学习的自动驾驶规划的极限 https://arxiv.org/abs/2404.14327 Abstract We present PLUTO, a powerful framework that Pushes the Limit of imitation learn…

【扇贝编程】python爬虫——爬取动态网页笔记

在示例网站上登陆后点开第一条请求&#xff08;wp-login.php&#xff09;。右边的 Headers 里可以看到请求地址&#xff08;Request URL&#xff09;为 https://wpblog.x0y1.com/wp-login.php&#xff0c;请求方式&#xff08;Request Method&#xff09;是 POST&#xff0c;状…

戴尔科技领涨市场,AI服务器需求成关键驱动力

戴尔科技强劲上涨&#xff0c;AI服务器需求激增 戴尔科技公司日内股价飙升4.2%&#xff0c;达到115.42美元&#xff0c;接近一个月高点。这一强劲表现主要得益于该公司上调了年度盈利预期&#xff0c;原因是对Nvidia驱动的人工智能优化服务器的需求显著增加。戴尔将2025财年的年…

RTC(实时时钟)/BKP(备份寄存器

1 unix时间戳 2 时间戳转换函数 3 BKP&#xff08;备份寄存器&#xff09; 1 TAMPER引脚侵入事件 2 RTC校准时间 3 RST闹钟脉冲和秒脉冲 可以输出出来为其他信号提供 4 校准时钟&#xff0c;寄存器加输出RTC校准时钟 5 总结&#xff1a;3个功能只能同时使用一个 4 BKP基本…