Object的变化侦测
? 变化侦测就是侦测数据的变化。当数据发生变化时,要能侦测到并且发出通知。
? Object可以通过 Object.defineProperty 将属性转换成getter/setter 的形式来追踪变化。读取数据时会触发 getter ,修改数据时会触发 setter。
? 我们需要在 getter 中收集有哪些依赖使用了数据,当 setter 被触发时,去通知 getter 中收集的依赖数据发生了变化。
? 收集依赖需要为依赖找寻一个可以存储依赖的地方,为此我们创建了 Dep ,它用来收集依赖,删除依赖和向依赖发送消息等。
? 所谓的依赖,其实就是 Watcher 。只有 Watcher 触发的 getter 才会收集依赖。哪个 Watcher 触发了getter,就把哪个 Watcher 收集到 Dep 中。当数据发生变化时,会循环依赖列表,把所有的 Watcher 都通知一遍。
? Watcher 的原理是先把自己设置到全局唯一的指定位置(例如 window.target),然后读取数据。因为读取了数据,所以会触发这个数据的 getter。接着,在 getter 中就会从全局唯一的那个位置读取当前正在读取数据的 Watcher ,并把这个 Watcher 收集到 Dep 中去,通过这样的方式,Watcher 可以主动去订阅任意一个数据的变化。
? 此外,我们创建了 Observer 类,它的作用是把一个 object 中的所有数据(包括子数据)都转换成响应式的,也就是它会侦测 object 中的所有数据(包括子数据)的变化。
? 由于 ES6 之前 JavaScript 并没有提供元编程的能力,所以在对象上新增属性和删除属性都无法被追踪到。为了解决这个问题,Vue.js提供了两个 API ---- vm.
s
e
t
与
v
m
.
set 与 vm.
set与vm.delete。
? 下图给出了Data、Observer、Dep 和 Watcher 之间的关系。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210709221302208.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQzNDkyMDY3,size_16,color_FFFFFF,t_70#pic_center)
? Data 通过 Observer 转换成了 getter/setter 的形式来追踪变化。
? 当外界通过 Watcher 读取数据时,会触发 getter 从而将 Watcher 添加到依赖中。
? 当数据发生了变化时,会触发 setter ,从而向 Dep 中的依赖 (Watcher)发送通知。
? Watcher接受到通知后,会向外界发送通知,变化通知到外界后可能会触发视图更新,也有可能触发用户的某个回调函数等。
|