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

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.lryc.cn/news/479927.html

相关文章:

  • Electron + Vue3 开发桌面应用+附源码
  • Webserver(5.2)网页服务器框架
  • 股指期货交易中,如何应对震荡行情?
  • 理想汽车Android面试题及参考答案
  • 【数据集】【YOLO】【目标检测】口罩佩戴识别数据集 1971 张,YOLO佩戴口罩检测算法实战训练教程!
  • 前端将后端返回的文件下载到本地
  • GISBox VS ArcGIS:分别适用于大型和小型项目的两款GIS软件
  • 掌握分布式系统的38个核心概念
  • 如何使用 VNC 服务器连接桌面
  • 算法每日练 -- 双指针篇(持续更新中)
  • 读取excel并且显示进度条
  • MySQL多表查询习题
  • HTML静态网页成品作业(HTML+CSS)——阜阳剪纸介绍设计制作(1个页面)
  • 创新引领,模块化微电网重塑能源格局
  • LeetCode34:在排序数组中查找元素第一个和最后一个位置
  • 汽车广告常见特效处理有哪些?
  • Unexpected response code: 400解决
  • 世优科技携手人民中科打造AI数字人智能体助力智慧校园
  • Mac intel 安装IDEA激活时遇到问题 jetbrains.vmoptions.plist: Permission denied
  • 区块链应用第1讲:基于区块链的智慧货运平台
  • 量化交易系统开发-实时行情自动化交易-风险控制
  • 深入探索 Seaborn:高级绘图的艺术与实践
  • 《现代工业经济和信息化》是什么级别的期刊?是正规期刊吗?能评职称吗?
  • 【TS】九天学会TS语法——2.TypeScript基本类型及变量声明
  • html+js+css实现拖拽式便签留言
  • Redis原理篇——Redis数据结构
  • pdf文件预览和导出
  • 服务器数据恢复—RAID5阵列硬盘坏道掉线导致存储不可用的数据恢复案例
  • 快速傅里叶变换(FFT)基础(附python实现)
  • 使用Docker-compose安装mysql5.7