You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
上面这段代码的主要作用在于 observer这个函数传入一个obj(需要被追踪变化的对象),通过遍历所有属性的方式对该对象的每一个属性都通过 defineReactive 处理,给每个属性加上 set 和 get 方法,以此来达到实现侦测对象变化. 值得注意的是, observe 会进行递归调用,那我们如何侦测Vue中 data 中的数据, 其实也很简单
classVue{/* Vue构造类 */constructor(options){this._data=options.data;observer(this._data);}}// 这样我们只要 new 一个 Vue 对象, 就会将 data 中的数据进行追踪变化. // 但是我们发现一个问题, 上面的代码无法检测到对象属性的添加或删除(如data.location.a=1,增加一个a属性)
Vue: vue响应式详解
🚀 1. 什么是Vue响应式
数据发生变化后,页面会重新进行渲染
, 这就是 Vue 的响应式🚀 2. 整个过程,需要做什么
数据劫持 / 数据代理
依赖搜集
发布订阅模式
🚀 3. 如何侦测数据的变化
Object.defineProperty
ES6
的Proxy
💛 Object.defineProperty的实现
Vue
通过设定对象属性的getter/setter
方法来监听数据的变化,通过getter
进行依赖搜集,而每个setter
方法就是一个观察者
,在数据变更的时候通知订阅者
更新视图observer
这个函数传入一个obj(需要被追踪变化的对象)
,通过遍历所有属性的方式对该对象的每一个属性都通过defineReactive
处理,给每个属性加上set
和get
方法,以此来达到实现侦测对象变化. 值得注意的是,observe
会进行递归调用,那我们如何侦测Vue
中data
中的数据, 其实也很简单Vue
通过Object.defineProperty
来将对象的key
转换成getter/setter
的形式来追踪变化, 但getter/setter
只能追踪一个数据是否被修改, 无法追踪新增属性和删除属性. 如果是删除属性, 我们可以用vm.$delete
实现, 那如果是新增属性, 该怎么办Vue.set(location, 'a', 1)
方法向嵌套对象添加响应式属性;data.location = {...data.location, a:1}
Object.defineProperty
不能监听数组的变化, 需要进行数组方法的重写💛 Proxy 实现
Proxy
是JavaScript 2015
的一个新特性.Proxy
的代理是针对整个对象的, 而不是对象的某个属性, 因此不同于Object.defineProperty
的必须遍历对象每个属性,Proxy
只需要做一层代理就可以监听同级结构下的所有属性变化, 当然对于深层结构, 递归还是需要进行的. 此外Proxy
支持代理数组的变化.🚀 4. 收集依赖
💛 4.1 为什么要收集依赖
location
数据, 当数据发生变化时,要向使用它的地方发送通知test1
以及test2
这两个Vue实例进行视图的更新,我们只有通过收集依赖才能知道哪些地方依赖我的数据, 以及数据更新时派发更新.那依赖收集是如何实现的?其中的核心思想就是事件发布订阅模式
.接下来我们先介绍两个重要角色--订阅者 Dep
和观察者 Watcher
, 然后阐述收集依赖的如何实现的.💛 4.2 订阅者 Dep
Watcher观察者
对象. 我们可以把Watcher理解成一个中介的角色, 数据发生变化时通知它, 然后它再通知其他地方🚀 5. 观察者 Watcher
💛 5.1 为什么引入Watcher
Watcher
类来表示观察订阅依赖
, 至于为啥引入Watcher
===> 当属性发生变化后, 我们要通知 用到数据 的地方,而使用这个数据的地方有很多, 而且类型还不一样, 既有可能是模板, 也有可能是用户写的一个watch,这时需要抽象出一个能集中处理这些情况的类, 然后, 我们在依赖收集阶段只收集这个封装好的类的实例进来, 通知也只通知它一个, 再由它负责通知其他地方.The text was updated successfully, but these errors were encountered: