ready
论坛版主
论坛版主
  • UID24
  • 粉丝0
  • 关注0
  • 发帖数433
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:1377回复:2

vue2的响应式原理

楼主#
更多 发布于:2024-07-11 15:41
Vue的响应式原理是用Object.definePrototy()的set与get结合观察者模式进行数据劫持;


首先了解一下Object.definePrototy()的set与get;


在获取对象prototy的时候,会自动调用get方法,在修改时会自动调用set方法


VUE给data里所有的属性加上set,get这个过程就叫做Reactive化。
————————————————






组件初始化时会给每一个data属性都注册一个getter,setter,也是就reactive化;


然后再new一个自己的Watcher对象,此时watcher会立即调用组件的render函数去生成虚拟DOM;


在调用render的时候需要用到data的属性值,此时会触发getter函数,将Watch函数进行注册;即依赖收集


当data属性发生改变时,会遍历所有的watch对象,notify它们去重新渲染组件!!


object里面如果是普通数据类型,直接return,若还包含其他对象或数组,会递归调用Object.definePrototy()
————————————————





vue2的响应式问题


vue2中利用的Object.definePrototy()写的方法会遍历所有的watch对象,十分耗费性能,而且需要对数组额外处理,
vue2中采用数组index下标直接修改数据是没有响应式的直接修改长度也是没有响应式的;初始化中没有在data中的数据也不是响应式的,后续可以通过Object.definePrototy()来添加或者$set等详见官网




vue3采用了proxy去替代Object.definePrototy()!!
————————————————


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/VegetableKCCCC/article/details/120430528
ready
论坛版主
论坛版主
  • UID24
  • 粉丝0
  • 关注0
  • 发帖数433
  • 社区居民
  • 忠实会员
  • 原创写手
沙发#
发布于:2024-07-11 15:49
Vue3.0的数据响应式原理是其核心特性之一,它极大地优化了开发体验并提高了性能。在Vue3中,响应式系统的实现主要依赖于ES6的`Proxy`和`Reflect`对象,这两个新特性使得Vue能够更加精细地监控数据的变化。

1. **ES6 Proxy**: `Proxy`允许我们创建一个代理对象,该对象可以拦截和控制对原始对象的操作。在Vue3中,当尝试访问或修改响应式对象时,`Proxy`会捕获这些操作,并触发相应的反应。例如,`reactive`函数就是利用`Proxy`将普通对象转换为响应式的。

2. **Composition API**: Vue3引入了Composition API,它允许开发者更灵活地组织和重用功能。`setup`函数是Composition API的关键部分,它在组件的`beforeCreate`和`created`生命周期钩子之间执行,用于初始化组件的状态。在这个函数中,你可以使用`reactive`和`computed`等响应式工具,返回的对象将作为组件实例的上下文。

3. **ReactiveEffect**: 这是Vue3响应式系统中的一个重要概念,它代表了一个可追踪的副作用函数。当响应式数据发生变化时,与之关联的`ReactiveEffect`会被调度执行,从而触发视图的更新。

4. **Dep和KeyToDepMap**: `Dep`是一个Set对象,用于存储所有依赖于某个响应式对象的`ReactiveEffect`。`KeyToDepMap`则是一个弱映射,它将响应式对象和它们的键映射到对应的`Dep`集合,用于高效地管理依赖关系。

在上述计数器例子中,`reactive`将`state`对象转换为响应式,当`count`属性被访问(如在模板中)时,会自动收集依赖。点击按钮调用`increment`函数,修改`state.count`,此时`Proxy`的`set`拦截器会被触发。由于`count`的改变,Vue3会检测到依赖并触发相关的`ReactiveEffect`,即更新视图,按钮上的数值随之更新。

Vue3.0的响应式系统相较于Vue2.x有了显著的优化,不仅减少了数据响应的开销,还提供了更高级的响应式功能,如`computed`属性和`ref`。`computed`用于计算属性,它会在依赖变化时自动重新计算。而`ref`则允许直接创建一个响应式的引用,它在某些场景下比`reactive`更为灵活。

Vue3.0的数据响应式原理是通过`Proxy`进行数据劫持,利用`Dep`和`ReactiveEffect`跟踪数据变化,以及`Composition API`简化组件逻辑,实现了高效的双向数据绑定。这一系列机制确保了Vue3应用能够在数据更新时自动同步视图,提供了一流的开发体验。
ready
论坛版主
论坛版主
  • UID24
  • 粉丝0
  • 关注0
  • 发帖数433
  • 社区居民
  • 忠实会员
  • 原创写手
板凳#
发布于:2024-07-11 15:52
响应式原理主要就是通过数据劫持,依赖收集,派发更新的方式来实现的


1.数据劫持,vue2是通过Object。defineProperty来将对象的每一个属性转化成set,get。


其中修改对象的属性时   就会触发set,   使用对象的属性时就会触发get


2.依赖收集。就是在渲染视图时  将watcher和具体的属性,通过发布订阅者模式管理,这样数据改变之后就能更精准的更新视图


3.派发更新:它就是通过dep来执行watcher的notify方法


使用Object.defineProperty做响应式的缺点


有三点


1.深度监听,需要一次性递归到底,计算量比较大


2.描述符只有get和set,无法监听新增属性和删除属性的操作


3.无法原生监听数组


这三个缺点中,第二点是defineProperty本身API的缺陷,而第一点和第三点都是出于性能考虑而做的取舍


解决缺点的方法


当我们通过数组的方法去更改数组时或是直接删除data数据,数据并不能实现响应式,因为Object.defineProperty是没有办法处理属性删除和新增的


因此vue2的响应式,通过数组方法(prop,push),或是删除,vue是不能监听的


vue2中通过vue2中可以通过vue.datele和vue.set这些vue内置api来改变属性,实现响应式。
————————————————


                            版权声明:https://blog.csdn.net/weixin_71718397/article/details/125859350
游客


返回顶部