Vue2/Vue3 响应式原理对比指南
Vue2/Vue3 响应式原理对比指南
1. 基本实现原理
1.1 Vue2 响应式实现 (Object.defineProperty)
// Vue2 响应式核心实现
function defineReactive(obj, key, val) {// 递归处理嵌套对象observe(val);const dep = new Dep();Object.defineProperty(obj, key, {get() {// 依赖收集if (Dep.target) {dep.depend();}return val;},set(newVal) {if (val === newVal) return;val = newVal;// 触发更新dep.notify();}});
}// 遍历对象所有属性
function observe(obj) {if (!obj || typeof obj !== 'object') return;Object.keys(obj).forEach(key => {defineReactive(obj, key, obj[key]);});
}
1.2 Vue3 响应式实现 (Proxy)
// Vue3 响应式核心实现
function reactive(target) {if (!isObject(target)) return target;const handler = {get(target, key, receiver) {// 依赖收集track(target, key);const result = Reflect.get(target, key, receiver);// 深层代理return isObject(result) ? reactive(result) : result;},set(target, key, value, receiver) {const oldValue = target[key];const result = Reflect.set(target, key, value, receiver);// 触发更新if (oldValue !== value) {trigger(target, key);}return result;},deleteProperty(target, key) {const hadKey = hasOwn(target, key);const result = Reflect.deleteProperty(target, key);if (hadKey && result) {// 触发更新trigger(target, key);}return result;}};return new Proxy(target, handler);
}
2. 核心差异对比
2.1 实现机制
特性 | Vue2 (Object.defineProperty) | Vue3 (Proxy) |
---|---|---|
拦截方式 | 属性级别拦截 | 对象级别拦截 |
初始化时机 | 初始化时递归遍历所有属性 | 访问时才进行代理(懒代理) |
内存占用 | 需要为每个属性创建getter/setter | 只需要一个代理对象 |
属性删除/添加 | 需要通过 Vue.set/Vue.delete | 可以直接监听 |
2.2 性能对比
- 初始化性能:
// Vue2 - 需要递归遍历所有属性
function observe(obj) {Object.keys(obj).forEach(key => {defineReactive(obj, key, obj[key]);// 递归处理嵌套对象if (typeof obj[key] === 'object') {observe(obj[key]);}});
}// Vue3 - 访问时才代理
const proxy = new Proxy(target, {get(target, key) {// 只在访问时才进行代理const value = Reflect.get(target, key);return isObject(value) ? reactive(value) : value;}
});
- 内存占用:
// Vue2 - 每个属性都需要定义getter/setter
const obj = { a: 1, b: 2, c: 3 };
// 需要创建3个getter/setter// Vue3 - 只需要一个代理对象
const proxy = new Proxy(obj, handler);
// 只需要创建一个Proxy实例
2.3 功能特性对比
- 数组操作:
// Vue2 - 需要重写数组方法
const arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice'];
arrayMethods.forEach(method => {// 重写数组方法以触发更新
});// Vue3 - 直接支持数组操作
const arr = reactive([1, 2, 3]);
arr.push(4); // 自动触发更新
arr[1] = 5; // 自动触发更新
- 新增属性:
// Vue2
const obj = { a: 1 };
// 新增属性需要使用 Vue.set
Vue.set(obj, 'b', 2);// Vue3
const obj = reactive({ a: 1 });
// 直接添加即可
obj.b = 2; // 自动触发更新
3. 优缺点分析
3.1 Vue2 (Object.defineProperty)
优点:
- 兼容性好,支持 IE8+
- 代码实现相对简单
缺点:
- 需要递归遍历对象所有属性
- 无法监听数组索引和长度变化
- 无法监听对象属性的添加和删除
- 需要额外的 API (Vue.set/Vue.delete)
3.2 Vue3 (Proxy)
优点:
- 性能更好(懒代理)
- 功能更强大(可以监听更多操作)
- 代码更简洁(不需要递归)
- 可以监听动态属性
缺点:
- 兼容性较差(不支持 IE11)
- 无法 polyfill
4. 为什么 Proxy 更高效?
- 初始化效率:
- Object.defineProperty 需要递归遍历对象的所有属性
- Proxy 采用懒代理,只在访问时才创建代理对象
- 内存占用:
- Object.defineProperty 需要为每个属性创建 getter/setter
- Proxy 只需要创建一个代理对象
- 操作拦截:
- Object.defineProperty 只能拦截属性的读写
- Proxy 可以拦截多达 13 种操作
- 数组处理:
- Object.defineProperty 需要重写数组方法
- Proxy 可以直接监听数组操作
5. 实际应用建议
- Vue2 项目:
- 避免深层嵌套数据结构
- 使用扁平化的数据结构
- 合理使用 Vue.set/Vue.delete
- Vue3 项目:
- 可以更自由地使用嵌套数据
- 直接操作数组和对象
- 利用 Proxy 的特性优化性能
6. 总结
Vue3 的响应式系统相比 Vue2 有显著改进:
- 性能更好
- 功能更强大
- 代码更简洁
- 开发体验更好
选择建议:
- 新项目建议使用 Vue3
- 需要兼容 IE11 的项目使用 Vue2
- 大型项目推荐 Vue3(性能优势明显)
相关文章:
Vue2/Vue3 响应式原理对比指南
Vue2/Vue3 响应式原理对比指南 1. 基本实现原理 1.1 Vue2 响应式实现 (Object.defineProperty) // Vue2 响应式核心实现 function defineReactive(obj, key, val) {// 递归处理嵌套对象observe(val);const dep new Dep();Object.defineProperty(obj, key, {get() {// 依赖收…...
FastExcel:超越EasyExcel的新一代Excel处理工具
简介 FastExcel是由原EasyExcel作者在阿里巴巴宣布停止维护EasyExcel之后推出的升级版框架。它继承了EasyExcel的所有优点,并且在性能和功能上进行了显著的提升和创新。 FastExcel的特点 高性能读写:FastExcel专注于性能优化,能够高效处理…...

大模型系列17-RAGFlow搭建本地知识库
大模型系列17-RAGFlow搭建本地知识库 安装ollama安装open-wehui安装并运行ragflowRAG(检索、增强、生成)RAG是什么RAG三过程RAG问答系统构建步骤向量库构建检索模块生成模块 RAG解决LLM的痛点 使用ragflow访问ragflow配置ollama模型添加Embedding模型添加…...
常用的mac软件下载地址
目录 iRightMouse Pro(超级右键) xmind(思维导图) Parallels Desktop(虚拟机工具) Paste(跨平台复制粘贴) AutoSwitchInput Pro(自动切换输入法) Snipa…...

基于51单片机和16X16LED点阵屏(74HC138和74HC595驱动)的小游戏《贪吃蛇》
目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、定时器02、自制八位独立按键3、点阵屏模块 四、主函数总结 系列文章目录 前言 《贪吃蛇》,一款经典的、怀旧的小游戏,单片机入门必写程序。 以《贪吃蛇》为载体,熟悉各种屏…...
python中常用的内置函数介绍
python中常用的内置函数介绍 1. print()2. len()3. type()4. str(), int(), float()5. list(), tuple(), set(), dict()6. range()7. sum()8. max(), min()9. sorted()10. zip()11. enumerate()12. map()13. filter()14. any(), all()15. abs()16. pow()17. round()18. ord(), …...

【微服务】Spring Cloud Config解决的问题和案例
文章目录 强烈推荐引言解决问题1. 配置管理的集中化2. 配置的版本控制3. 环境特定配置4. 配置的动态刷新5. 安全管理敏感数据6. 配置的一致性 组件1. **配置服务器(Config Server)**2. **配置客户端(Config Client)** 配置示例配置…...
华为OD机试E卷 --最小的调整次数--24年OD统一考试(Java JS Python C C++)
文章目录 题目描述输入描述输出描述用例题目解析JS算法源码Java算法源码python算法源码c算法源码c++算法源码题目描述 有一个特异性的双端队列一,该队列可以从头部或尾部添加数据,但是只能从头部移出数据。 小A依次执行2n个指令往队列中添加数据和移出数据。其中n个指令是添…...
Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(2):配置主数据库
Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(2):配置主数据库 目录 Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(2):配置主数据库一、配置…...
慧集通iPaaS集成平台低代码训练-实践篇
练习使用帐号信息: 1.致远A8平台(请自行准备测试环境) 慧集通连接器配置相关信息 访问地址: rest账号:rest rest密码: OA账号: 2.云星空(请自行准备测试环境) 连接…...
TDengine 如何进行高效数据建模
1.背景 数据建模对于数据库建立后整体高效运行非常关键,不同建模方式,可能会产生相差几倍的性能差别 2. 建库 建模在建库阶段应考虑几下几点: 建多少库 根据业务情况确定建库个数,TDengine 不支持跨库查询,如果业…...

HarmonyOS NEXT应用开发实战:一分钟写一个网络接口,JsonFormat插件推荐
在开发鸿蒙操作系统应用时,网络接口的实现往往是一个繁琐且重复的过程。为了提高开发效率,坚果派(nutpi.net)特别推出了一个非常实用的插件——JsonFormat。这款插件的主要功能是将JSON格式的数据直接转换为arkts的结构定义,让我们在编写接口…...
基于动力学的MPC控制器设计盲点解析
文章目录 Apollo MPC控制器的设计架构误差模型和离散化预测模型推导目标函数和约束设计优化求解优化OSQP求解器参考文献 Apollo MPC控制器的设计架构 误差模型和离散化 状态变量和控制变量 1、Apollo MPC控制器中状态变量主要有如下6个 matrix_state_ Matrix::Zero(basic_stat…...
Java重要面试名词整理(十六):SpringBoot
由于SpringBoot和Spring、SpringMVC重合度较高,更多详细内容请参考https://blog.csdn.net/weixin_73195042/article/details/144632385 本文着重于SpringBoot的启动流程 文章目录 概念启动流程底层分析构造SpringApplication对象run(String... args)方法SpringBoo…...

在K8S中,如何部署kubesphere?
在Kubernetes集群中,对于一些基础能力较弱的群体来说K8S控制面板操作存在一定的难度,此时kubesphere可以有效的解决这类难题。以下是部署kubesphere的操作步骤: 操作部署: 1. 部署nfs共享存储目录 yum -y install nfs-server e…...
算法-查找缺失的数字
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。 示例 1: 输入:nums [3,0,1] 输出:2 解释:n 3,因为有 3 个数字,所以所有的数字都在范围 [0,3…...

antd-vue - - - - - a-date-picker限制选择范围
antd-vue - - - - - a-date-picker限制选择范围 1. 效果展示2. 代码展示 1. 效果展示 如图:限制选择范围为 今年 & 去年 的 月份. 2. 代码展示 <template><a-date-picker:disabledDate"disabledDate"picker"month"/> &l…...

计算机网络练习题
学习这么多啦,那就简单写几个选择题巩固一下吧! 1. 在IPv4分组各字段中,以下最适合携带隐藏信息的是(D) A、源IP地址 B、版本 C、TTL D、标识 2. OSI 参考模型中,数据链路层的主要功能是(…...

redis的集群模式与ELK基础
一、redis的集群模式 1.主从复制 (1)概述 主从模式:这是redis高可用的基础,哨兵和集群都是建立在此基础之上。 主从模式和数据库的主从模式是一样的,主负责写入,然后把写入的数据同步到从服务器ÿ…...

STM32-笔记18-呼吸灯
1、实验目的 使用定时器 4 通道 3 生成 PWM 波控制 LED1 ,实现呼吸灯效果。 频率:2kHz,PSC71,ARR499 利用定时器溢出公式 周期等于频率的倒数。故Tout 1/2KHZ;Ft 72MHZ PSC71(喜欢设置成Ft的倍数&…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...