Open JuniorTour opened 2 years ago
TODO 正在热火朝天更新中,欢迎催更~
Watcher
updateComponent()
new Watcher(this, updateComponent)
constructor
this.get()
Dep.target
data
defineProperty()
getter
dep.depend()
dep
subs
this.subs.push(sub)
updateComponent
null
当数据更新后,例如执行:vm._data.msg = "数据驱动 DOM 更新”
vm._data.msg = "数据驱动 DOM 更新”
setter
dep.notify()
this.subs
.update()
_render()
DEMO:https://jsbin.com/hehicek/edit?html,console,output
TODO 正在热火朝天更新中,欢迎催更~
Vue.js 数据驱动 && 订阅发布模式原理
Vue实例初始化时收集订阅
Watcher
,初始化时第一次调用updateComponent()
渲染出虚拟DOM:new Watcher(this, updateComponent)
Watcher
初始化时,constructor
中会调用一次Watcher
实例的回调this.get()
Dep.target
设置为当前的Watcher
实例data
每个属性的值,触发其defineProperty()
设置的getter
getter
中会调用dep.depend()
收集当前的Dep.target
作为订阅者,添加到dep
实例的subs
属性中 (this.subs.push(sub)
)updateComponent
完成后,会卸载Dep.target
,设置为null
数据驱动发布更新视图
当数据更新后,例如执行:
vm._data.msg = "数据驱动 DOM 更新”
defineProperty()
设置的setter
setter
中会调用dep.notify()
,遍历所有的订阅者(this.subs
),并调用订阅者的.update()
方法发布更新Watcher
的.update()
方法会再次调用其第二个参数回调函数,执行一次updateComponent
updateComponent
,调用_render()
,渲染出新的虚拟DOM,经过Diff,同步到真实DOM中,就完成了一轮「数据驱动」的视图更新。