Vue数据响应式原理

前言

Vue是一个结构的框架,也就是 数据层、视图层、数据-视图层;响应式的原理就是实现当数据更新时,视图层也要相应的更新

响应式实现

基于发布订阅模式和数据劫持实现

1.发布订阅模式:vue使用发布订阅模式来实现数据变动的通知和更新

2.数据劫持:vue通过object.defineProperty对数据进行劫持

Vue2响应式原理

基于js的object.defineProperty() 方法,该方法可将传入的属性全部转为getter/setter

object.defineProperty() 实现数据拦截是再数据被访问和被修改的时候进行拦截

1.数据劫持:vue2的data部分会被object.defineProperty()传入并转成getter/setter,便于追踪属性的变化,在属性被修改的时候执行相应的操作

2.依赖追踪:vue中有一个依赖收集系统,每一个响应式数据都会有一个依赖集合,当访问到该数据的时候会把当前的watcher记录下来,后续数据发生变化的时候,依赖于这个数据的watcher会被通知去更新相应的视图

3.派发更新:当响应式数据变化的时候,vue会遍历依赖集合,通知相应的watcher更新视图

Object.defineProperty

为什么vue3要使用proxy而不是继续使用Object.defineProperty

1.兼容性问题:一些旧版本浏览器不兼容

2.只能监听对象属性:只能劫持对象的属性访问和修改操作,无法监听对象的新增属性和删除属性的操作,所以如果一个对象要新增属性需要使用vue.set()

3.无法监听数组的变化:对于数组的增加,删除和重排不会触发数组的属性变化,从而也不会被拦截,再vue中响应式处理需要使用push,pop()等方法去实现

4.性能开销:对于大规模的data数据,每个被劫持的对象都要有对应的getter和setter进行拦截和更新,可能会影响到整体性能

Vue3响应式原理

Vue2使用ES5的Object.defineProperty() API对数据进行劫持,并结合发布订阅模式实现双向数据绑定。而Vue3则使用ES6的Proxy API对数据进行代理,从而进行双向数据绑定。使用Proxy API可以省去for in、闭包等内容来提升效率,同时可以监听整个对象,而不仅仅是某个属性。另外,Proxy API还可以检测到数组内部数据的变化。

Proxy

1.可定制行为:通过定义拦截器函数,可以对对象的各种操作进行定制,使得 Proxy 对象能够实现非常灵活的代理行为。
2.透明性:Proxy 对象与原对象具有相同的外观和行为,因此在代码中可以完全替代原对象,而不会影响到代码的其他部分。
3.非侵入性:Proxy 对象与原对象之间的代理关系是动态的,可以随时添加或移除代理行为,而不会影响到原对象。
4.更好的性能:与 Object.defineProperty() 相比,Proxy 的性能通常更好,特别是在处理大规模数据和数组变化

区别

1.灵活性:Proxy 提供了更加灵活和强大的拦截能力,可以拦截对象的更多操作,包括属性的读取、赋值、删除、枚举等,以及数组的操作如 push、pop、shift、unshift 等。而 Object.defineProperty() 只能劫持对象的属性访问和修改操作,无法直接监听数组的变化等
2.兼容性:Proxy 在 ES6 中被引入,因此对于支持 ES6 的现代浏览器和环境来说,兼容性较好。但是在一些旧版本的浏览器中,如 IE11 及更早版本,Proxy 并不被支持。而 Object.defineProperty() 在较早的 ES5 中就已经存在,兼容性较好,但也存在一些兼容性问题,如无法监听数组变化和对新增属性的处理等
3.性能:Proxy 相对于 Object.defineProperty() 在性能上可能会有所提升,特别是在处理大规模数据和数组变化时。Proxy 的拦截器函数在实现上更为底层,因此可能更加高效。而 Object.defineProperty() 的性能开销相对较大,特别是在属性较多时可能会影响到整体性能
4.监听对象的方式:Proxy是通过创建一个目标对象的代理对象来实现监听的,可以直接监听整个对象,包括对象的属性新增、删除和修改等操作。而Object.defineProperty()是针对对象的每个属性进行劫持,无法直接监听对象的整体变化

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

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

相关文章

python函数小练习(三)

main.py import testwhile True:test.kdc_menu()ch int(input("请选择>>"))match ch:case 1:test.show_menu()case 2:test.sale_menu()case 3:test.money_menu()case 4:test.mess_menu()case -1:breakcase _:print("请重新输入")test.py menu {…

vue3 + element-plus 的 upload + axios + django 文件上传并保存

之前在网上搜了好多教程,一直没有找到合适自己的,要么只有前端部分没有后端,要么就是写的不是很明白。所以还得靠自己摸索出来后,来此记录一下整个过程。 其实就是不要用默认的 action,要手动实现上传方式 http-reque…

更改Ubuntu22.04锁屏壁纸

更改Ubuntu22.04锁屏壁纸 sudo apt install gnome-shell-extensions gnome-shell-extension-manager安装Gnome Shell 扩展管理器后,打开“扩展管理器”并使用搜索栏找到“锁屏背景”扩展

SDL打开YUV视频

文章目录 问题1:如何控制帧率?问题2:如何触发退出事件?问题3:如何实时调整视频窗口的大小问题4:YUV如何一次读取一帧的数据? 问题1:如何控制帧率? 单独用一个子线程给主线…

SQL server 中 CROSS APPLY的使用

CROSS APPLY 是 SQL Server 中的一个操作符,用于将一个表表达式(如子查询、函数等)与外部表进行连接。CROSS APPLY 类似于 INNER JOIN,但它允许你在一个查询中多次引用外部表的行,并且可以动态地生成结果集。 基本语法…

【算法】Floyd多源最短路径算法

目录 一、概念 二、思路 三、代码 一、概念 在前面的学习中,我们已经接触了Dijkstra、Bellman-Ford等单源最短路径算法。但首先我们要知道何为单源最短路径,何为多源最短路径 单源最短路径:从图中选取一点,求这个点到图中其他…

纯C++信号槽使用Demo (sigslot 库使用)

sigslot 库与QT的信号槽一样,通过发送信号,触发槽函数,信号槽不是QT的专利,早在2002年国外的一小哥用C写了sigslot 库,简单易用; 该库的官网(喜欢阅读的小伙伴可以仔细研究)&#xf…

【路径规划】PID搜索算法PSA求解UAV路径规划

摘要 本文研究了基于PID搜索算法(PID Search Algorithm, PSA)求解无人机(UAV)路径规划问题。通过引入PID控制思想来控制路径生成过程,使得无人机可以避开障碍物并在复杂地形中寻找最优路径。实验结果表明,…

【大数据学习 | kafka高级部分】kafka的数据同步和数据均衡

1. 数据同步 通过上图我们发现每个分区的数据都不一样,但是三个分区对外的数据却是一致的 这个时候如果第二个副本宕机了 但是如果是leader副本宕机了会发生什么呢? 2. 数据均衡 在线上程序运行的时候,有的时候因为上面副本的损坏&#xff…

java:使用Multi-Release Jar改造Java 1.7项目增加module-info.class以全面合规Java 9模块化规范

common-java是一个我维护了好多年的一个基础项目,编译目标为Java 1.7 现在整个团队的项目要做Java 9以上的技术迁移准备,就需要对这个在内部各项目中被广泛引用的基础项目进行改造,以适合Java 9的模块化规范。 Automatic-Module-Name Java 9的模块化规范(即Java Platform Mod…

二叉树的前中后序遍历

前序遍历:中左右 中序遍历:左中右 后序遍历:左右中 递归法:三种遍历方式代码结构相似,需要搞清楚三个内容:递归函数的返回值,递归函数传递的参数以及递归函数结束的条件 代码随想录 迭代法:需要用栈实现,前序和后序类似,中序…

如何一步步实现api接入JD平台通过url获取item get商品详情字段信息

以下是一步步实现通过 API 接入京东(JD)平台并使用 URL 获取商品详情(Item Get)字段信息的大致步骤: 一、注册成为京东开发者并获取 API 权限 注册开发者账号 访问京东api文档,点击注册按钮,按照…

Ubuntu笔记-auto remove

apt autoremove确实是一个非常有用的命令,它用于自动删除系统中不再需要的依赖包。这些依赖包通常是在安装某些软件时自动安装的附加包,而当这些软件被卸载后,这些依赖包也就失去了作用。 然而,许多博客和用户提醒说 apt autorem…

机器视觉基础—双目相机

机器视觉基础—双目相机与立体视觉 双目相机概念与测量原理 我们多视几何的基础就在于是需要不同的相机拍摄的同一个物体的视场是由重合的区域的。通过下面的这种几何模型的目的是要得到估计物体的长度,或者说是离这个相机的距离。(深度信息&#xff09…

C++继承(图文非常详细)

继承的概念 1.什么是继承 1.简单定义 我们来看一下下面这串代码注意其中的两个类father 和 son using namespace std; #include<iostream> class father { public:void definity(){cout << "father" << endl;} protected:int tall 180;int age …

解决PyQt5多线程报错:QThread: Destroyed while thread is still running

在使用PyQt5进行多线程开发时&#xff0c;许多初学者会遇到一个常见的问题&#xff1a;程序在运行时没有任何明显的错误信息&#xff0c;但却在终端中报出QThread: Destroyed while thread is still running的警告。而在PyCharm等IDE中&#xff0c;只会看到Process finished wi…

Python中的数据类(dataclass):简化类的定义与数据管理的全面指南

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! Python 3.7引入的数据类(dataclass)极大地简化了类的定义,尤其在处理数据管理任务时。数据类自动生成__init__、__repr__等方法,帮助开…

详细介绍MySQL、Mongo、Redis等数据库的索引

MySQL 索引 概念与类型 MySQL 索引是一种数据结构&#xff0c;用于快速查找数据库中的数据。它就像一本书的目录&#xff0c;通过索引可以快速定位到需要的数据行&#xff0c;而不必全表扫描。主要的索引类型包括 B - Tree 索引&#xff08;默认索引类型&#xff09;、哈希索引…

torch.full函数介绍

torch.full 是 PyTorch 中用于创建一个具有指定形状、填充值和数据类型的张量的函数。它非常适用于需要初始化特定数值的张量的情况,比如将所有元素填充为一个常量值。 函数定义 torch.full(size, fill_value, *, dtype=None, layout=torch.strided, device=None, requires_…

Unity自动打包——Shell交互

Unity 无论是测试还是上线都需要打包&#xff0c;而每次打包我们还要打各种平台&#xff08;安卓、Ios、WebGL、Windows…&#xff09;,有可能不同的打包时机还要有不同的配置项&#xff0c;这种工作枯燥、繁琐且易错&#xff0c;为了解决这一困扰就想到了能不能做一个工具来专…