《源码系列》助你理解vue响应式源码——实现Watcher观察者
内容提要
本文介绍了Vue中实现双向数据绑定的原理。主要由Compile、Observer、Dep、Watcher四部分组成。Compile用于初始化视图,解析指令并将对应的值渲染到页面上。Dep用于增加订阅者和通知Watcher更新视图。Watcher用于更新视图,比较新旧值并执行回调函数替换数据。Observer使用Object.defineProperty对数据进行监听,get方法进行依赖收集,set方法通知Dep中的观察者更新视图。
延伸解读
Dep与Watcher的关联机制
文章通过Dep.target这一全局变量,在Watcher实例化时临时将自身赋值给Dep.target,随后在Observer的getter中检查Dep.target是否存在,若存在则将其加入Dep的订阅者列表。这种设计确保了每个数据属性只收集当前正在求值的Watcher,避免了重复订阅,是Vue响应式系统中依赖收集的关键技巧。
Watcher的更新闭环设计
Watcher在构造时通过getOldValue获取旧值,并利用Dep.target完成依赖收集。当数据变化触发setter时,Dep.notify会调用所有Watcher的update方法,update中重新获取新值并与旧值比较,若不同则执行编译阶段传入的回调函数更新视图。这一闭环保证了数据变化到视图更新的自动化流程。
实现中的注意事项
文章在getOldValue中通过Dep.target = this和Dep.target = null的成对操作,确保只添加一次观察者。同时,在defineReactive的setter中,先对新值调用observer进行递归监听,再比较新旧值,若不同则更新闭包中的value并触发notify。这些细节避免了重复订阅和无效更新,是手写响应式代码时需要留意的点。
Q&A
Vue的双向数据绑定是如何实现的?
Vue的双向数据绑定主要通过Compile、Observer、Dep和Watcher四个部分协作实现。
什么是Watcher在Vue中的作用?
Watcher用于更新视图,比较新旧值并执行回调函数以替换数据。
Dep类在Vue中是做什么的?
Dep类用于管理观察者,增加订阅者并通知Watcher更新视图。
Observer是如何监听数据变化的?
Observer使用Object.defineProperty对数据进行监听,通过get方法进行依赖收集,set方法通知观察者更新视图。
Compile在Vue中有什么作用?
Compile用于初始化视图,解析指令并将对应的值渲染到页面上。
Vue的双向数据绑定如何确保数据变化时视图更新?
通过Watcher比较新旧值并调用回调函数,结合Dep通知观察者更新视图,形成闭环。