当前位置: 首页 > article >正文

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.kler.cn/a/388160.html

相关文章:

  • 探索Pillow库:Python图像处理的瑞士军刀
  • Spring框架之观察者模式 (Observer Pattern)
  • 网站小程序app怎么查有没有备案?
  • 【初阶数据结构与算法】链表刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
  • 使用kalibr_calibration标定相机(realsense)和imu(h7min)
  • Android 配置默认输入法
  • Cent OS-7的Apache服务配置
  • 【Python进阶】Python网络协议与套接字编程:构建客户端和服务器
  • IntelliJ IDEA快速接入LLMs大模型API
  • GISBox VS ArcGIS:分别适用于大型和小型项目的两款GIS软件
  • Gen-RecSys——一个通过生成和大规模语言模型发展起来的推荐系统
  • 钉钉调试微应用整理2
  • Jenkins 构建时候提示超时错误被终止
  • JVM知识点大全(未完...)
  • 【自用】时序数据库、时序数据库,IOTDB官方文档笔记
  • 【划分型 DP】力扣139. 单词拆分
  • Unity 实现数字垂直滚动效果
  • 高性能分布式缓存Redis-高级应用篇章
  • HTML的文本样式(二)
  • 阿里 Sentinel
  • 【C++】新手入门指南
  • core-js 解决浏览器兼容性问题的工具之一
  • Rust: 利用 chrono 库实现日期和字符串互相转换
  • Spring学习笔记(二)
  • scrapy爬取中信证券销售金融产品信息
  • git tag