vue是如何监听对象和数组变化的

Vue框架通过其响应式系统来监听对象和数组的变化。这个系统的核心在于追踪依赖关系,并在数据变化时通知所有依赖于该数据的观察者。

 

1. 对象监听

Vue使用`Object.defineProperty`方法来劫持各个属性的getter和setter。当组件中的数据被读取时,会触发getter函数,在getter函数内部进行依赖收集;当数据被修改时,setter函数会被触发,进而通知所有依赖于该属性的观察者进行更新。这种方式使得Vue可以精确地跟踪每个属性的变化,并进行高效的更新,还可以使用Object.assign()直接赋值来替换整个对象,可以触发视图更新。

2. 数组监听

由于JavaScript的原生数组方法(如`push`、`pop`、`splice`等)不会触发`Object.defineProperty`中的setter,Vue对数组的原生方法进行了重写,使其也可以触发视图更新。另外,Vue还提供了`Vue.set`方法或`Array.prototype.splice`来确保新增的元素也是响应式的。对于删除操作,Vue会通过索引跟踪依赖,确保删除操作能够被监听到。

3. 依赖收集

在组件渲染过程中,如果一个数据被读取,那么这个数据就会被添加到这个组件的依赖列表中。当数据发生变化时,Vue会遍历这个依赖列表,并通知所有依赖这个数据的部分进行更新。

4. Watcher

Vue的内部机制创建了Watcher对象,这些对象负责追踪自己依赖的数据,并在数据变化时执行回调函数以更新视图。每个组件实例都有一个Watcher实例与之对应,用于监听该组件模板所依赖的数据。

5. 异步队列

为了优化性能,Vue还会将这些更新放入一个异步队列,然后使用`nextTick`方法将这些更新在下一个DOM循环中一次性应用,这样可以减少不必要的DOM操作,提高渲染效率。

6. 虚拟DOM(VDOM)

Vue使用虚拟DOM来表示真实的DOM结构,当监听到数据变化时,Vue会生成新的虚拟节点与老的虚拟节点进行比较,然后通过一个diff算法计算出最小的变更步骤来更新真实的DOM。

 

总结来说,Vue通过定义属性的getter和setter以及重写数组方法来监听对象和数组的变化。当数据变化被监听到后,Vue通过内部的Watcher机制和虚拟DOM技术来确保视图能够高效且准确地更新。


在 Vue2 中,响应式原理**基于 Object.defineProperty** 实现,而在 Vue3 中,响应式原理是**通过 Proxy 对象实现的**。

Vue2 的响应式原理利用了 JavaScript 中的 `Object.defineProperty` 方法。此方法允许开发者定义对象属性的 getter 和 setter,使得当这些属性被读取或赋值时,可以执行自定义的操作。Vue2 在初始化过程中会遍历 data 对象的所有属性,为每个属性设置 getter 和 setter,同时收集依赖(即哪些地方使用了这个属性),并在属性值改变时通知这些依赖进行更新。

Vue3 则采用了 ES6 的 `Proxy` 对象来实现响应式。`Proxy` 可以代理对象的全部属性,并且能够轻松地对新增或删除的属性进行处理。与 `Object.defineProperty` 相比,它能够在更多操作(如数组索引的变更)上提供拦截能力。Vue3 结合了 `Reflect` 来确保 `Proxy` 处理中的一致性和正确性。

两者的主要区别在于:

1. **监听方式**:Vue2 使用的是属性级别的监听,而 Vue3 实现了对象级别的全局监听。
2. **新增和删除属性**:Vue2 对于对象新增或删除的属性无法做出响应式处理,除非使用特定的 API 方法;Vue3 由于使用了 Proxy,能够自然地处理这种情况。
3. **性能**:在 Vue2 中,由于需要递归遍历所有属性,在处理具有大量属性的对象时可能会有性能损耗。而 Vue3 通过 Proxy 避免了这种递归过程,提高了性能。

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

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

相关文章

ROS2服务通信的实现

文章目录 1.服务通信的概念及应用场景1.1概念1.2 应用场景 2.准备工作3.服务通信的实现3.1 服务通信接口消息3.2 服务端实现3.3 客户端实现3.4 编译及运行3.4.1 修改CMakeLists3.4.2 服务端运行结果3.4.2 客户端运行结果 1.服务通信的概念及应用场景 1.1概念 服务通信也是ROS…

抖店0元入驻不交钱会怎么样?个人店和个体店的利弊分析,开店必看

我是王路飞。 现在的抖店是可以开通个人店的。 也就是不需要营业执照、直接使用个人身份证就可以在抖音开店,而且也不需要缴纳店铺保证金就能开店运营了。 但真实情况是怎么样的呢?新手0元入驻抖店不交这个保证金会怎么样呢? 今天给想在抖…

AI大预言模型——ChatGPT在地学、GIS、气象、农业、生态、环境应用

原文链接:AI大预言模型——ChatGPT在地学、GIS、气象、农业、生态、环境应用 一开启大模型 1 开启大模型 1)大模型的发展历程与最新功能 2)大模型的强大功能与应用场景 3)国内外经典大模型(ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diff…

ios App 发送广播失败解决

记录开发 ios App 使用 c 混编时遇到的问题: 开发环境 macOS Sonoma(最新版本14.3.1) Xcode Version 15.2 ipadOS(最新版本17.3.1) 问题:在mac 上 和 ipad上测试,当 udp 发送广播&#xff…

跨域引起的两个接口的session_id不是同一个

来源场景: RequestMapping(“/captcha”)接口设置了SESSION_KEY,也能获取到,但是到了PostMapping(“/login”)接口就是空的,由于跨域导致的两个session_id不是同一个 /*** 系统用户 前端控制器*/ Controller CrossOrigin(origins…

【数据结构和算法初阶(C语言)】双向循环带头链表的增删查改详解(天才设计的链表结构,应用简单逆天!!!!!)

目录 ​编辑​编辑 1.双向链表的定义:前赴后继 2.带头链表的定义-----哨兵位 3.增删查改 3.1创建新节点函数----方便后续增加节点调用 3.2创建哨兵位----创建头结点 3.3增加节点,尾部插入数据 3.4尾删除 3.5查找函数----遍历对比&#xff…

AcWing 562.壁画

咱先看一眼算法标签,发现是思维题、枚举、前缀和 Buttt其实我们根据上诉的样例解释部分就会发现,其实这就是一个长度为⌈n/2⌉(向上取整哦)的连续子数组的最大和。 这题我也用暴力法试过啦,很明显会TLE 如果你对dp题…

Mac M系列芯片如何重新安装系统

使用可引导安装器重新安装(可用于安装非最新的 Mac OS,系统降级,需要清除所有数据,过程确保连接上网络,虽然这种方式不会下载 Mac OS,但是需要下载固件等信息) 插入制作好的可引导安装器&#x…

【使用imgaug库调整图像大小并修改对应的XML标签框】

使用imgaug库可以方便地进行图像增强操作,包括调整图像大小。以下是使用imgaug库调整图像大小并修改对应的XML标签框的示例脚本: 注意修改输入文件夹路径、输出文件夹路径和目标尺寸为自己内容。 input_folder "path/to/your/input_folder" …

kalibr标定ZED2i双目加imu

一、录制bag 本人使用的zed2i相机。 rosbag record -O 32 /zed2i/zed_node/imu/data /zed2i/zed_node/imdata_raw /zed2i/zed_node/left/image_rect_color /zed2i/zed_node/right/image_rect_color /zed2i/zed_node/left_raw/image_raw_color /zed2i/zed_node/right_raw/ima…

Matlab|【免费】基于合作博弈的综合能源系统利益分配优化调度

目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序实现的模型为综合能源系统利益分配优化调度,采用合作博弈方法,模型针对IES系统的P2G、电解槽、甲烷反应器、储氢罐、CHP和燃气锅炉等设备进行建模,实现基于合作博弈的…

std::shared_from_this注意事项:exception bad_weak_ptr

1.不可以在构造函数中调用shared_from_this() 因为它的实现是&#xff1a; _LIBCPP_INLINE_VISIBILITYshared_ptr<_Tp> shared_from_this(){return shared_ptr<_Tp>(__weak_this_);}也就是它依赖的__weak_this_此时还未创建完成。 2.一定要public继承 class MyTy…

大数据开发(Java面试真题-卷二)

大数据开发&#xff08;Java面试真题&#xff09; 1、请简要说明Java中equeals()和hashCode()的作用及区别&#xff1f;2、Java中的四种访问修饰符及它们之间的区别&#xff1f;3、请解释Java中的异常处理机制&#xff0c;包括checked exception和unchecked exception?4、Java…

Linux 学习笔记(10)

十、 进程管理 进程就是运行中的程序&#xff0c;一个运行着的程序&#xff0c;可能有多个进程。 比如 LinuxSir.Org 所用的 WWW 服务器是 apache 服务器&#xff0c;当管理员启动服务后&#xff0c;可能会有好多人来访问&#xff0c;也就是说许多用户来同时请 求 htt…

QT debug编译失败:xxx/bin/ld.exe: cannot find -lxxd1

原因&#xff1a;由于编译时&#xff0c;使用debug模式下&#xff0c;动态库没有对应的lxxd1中的xx库 解决方案1&#xff1a;改为release编译&#xff1b; 解决方案2&#xff1a;在引用的三方pri文件中&#xff0c;去掉多余的d #修改前 if(!debug_and_release|build_pass):CON…

沃德的背包

题目描述 沃德进入源码世界的路上有很多宝石&#xff0c;可是沃德的背包只能背总重量不超过m的宝石&#xff0c;路上一共有n个宝石&#xff0c;每个宝石的重量为wi&#xff0c;请你帮沃德选择尽量多的宝石装进背包&#xff0c;请注意宝石的总重量不超过m。 输入描述 第一行输…

Django官网项目 二

官网地址&#xff1a;Writing your first Django app, part 2 | Django documentation | Django 创建模组&#xff1a; 注册model &#xff08;bug&#xff1a;没有加后面的逗号&#xff09; 在manage.py 的目录下&#xff1a; python manage.py makemigrations polls pyth…

redis09 集群(cluster)

思维草图 为什么要使用集群 单台redis内存容量的限制单台redis并发写量太大有性能瓶颈 redis集群认识 redis集群是对redis的水平扩容&#xff0c;即启动N个redis节点&#xff0c;将整个数据分布存储在这个N个节点中&#xff0c;每个节点存储总数据的1/N。 如下图&#xff1…

C++ 根据公式计算椭圆任意点到中心的距离

#include <iostream> using namespace std;double fact(int x) //定义阶乘函数。注意是double类型 {double y x; //注意是double类型for (int i x-1; i > 0; i--)y * i;return y; };double My_sin(int x) //定义sin函数。注意是double类型 {double y 0; //注意是do…

【视频图像取证篇】Amped FIVE专业法医图像和视频增强软件之模糊图像去隔行功能

【视频图像取证篇】Amped FIVE专业法医图像和视频增强软件之模糊图像去隔行功能 法医图像和视频增强软件&#xff0c;专业又强大&#xff01;&#xff01;&#xff01;超过 140 种过滤器和工具&#xff0c;用于分析、恢复和增强数字图像和视频。Amped FIVE能够稳定抖动的视频&…