现代前端框架有两种方式侦测变化,一种是
pull
一种是push
pull
: 其代表为React
,我们可以回忆一下React
是如何侦测到变化的,我们通常会用setStateAPI
显式更新,然后React
会进行一层层的Virtual Dom Diff
操作找出差异,然后Patch
到DOM
上,React
从一开始就不知道到底是哪发生了变化,只是知道「有变化了」,然后再进行比较暴力的Diff
操作查找「哪发生变化了」,另外一个代表就是Angular
的脏检查操作。push
:Vue
的响应式系统则是push
的代表,当Vue
程序初始化的时候就会对数据data
进行依赖的收集,一但数据发生变化,响应式系统就会立刻得知,因此Vue
是一开始就知道是「在哪发生变化了」,但是这又会产生一个问题,如果你熟悉Vue
的响应式系统就知道,通常一个绑定一个数据就需要一个Watcher
,一但我们的绑定细粒度过高就会产生大量的Watcher
,这会带来内存以及依赖追踪的开销,而细粒度过低会无法精准侦测变化,因此Vue
的设计是选择中等细粒度的方案,在组件级别进行push
侦测的方式,也就是那套响应式系统,通常我们会第一时间侦测到发生变化的组件,然后在组件内部进行Virtual Dom Diff
获取更加具体的差异,而Virtual Dom Diff
则是pull
操作,Vue
是push+pull
结合的方式进行变化侦测的