初始化阶段
computed会为每一个属性都创建各自的computed watcher,同时还有dep(这个dep用来收集页面渲染的render wacher和 别的计算属性的computed watcher,因为计算属性可以相互依赖),还有一个名叫dirty的flag(用于优化缓存,下面会讲)。并把watcher加入到Dep.target中,然后执行他的回调函数。
执行函数过程中触摸(touch)到他的依赖,也就是data中的属性,此时就会触发data属性的getter方法,把computed watcher加入到data属性的dep的subs数组中,这样就完成了data的依赖收集。
同时还会有计算属性相互依赖的情况,别的计算属性在触摸的过程中还会触摸到当前的计算属性,这样就会把别的计算属性的computed watcher加入到当前计算属性的dep的subs数组中,完成computed的依赖收集
页面渲染时
渲染时,computed属性会跟data属性做一样的render watcher收集,如果computed在页面中有渲染,这样这个computed的dep就相当于持有了刷新页面的能力,否则就没有。
运行时:
当一个计算属性他的依赖(data或者computed)修改时,执行一遍回调函数,看值有没有变化,如果没有变化直接什么都不做(缓存优化)
否则就分下面两种情况:
当这个计算属性他的subs数组不为空:
data会遍历他的dep的subs数组,调用他们的update方法,对render watcher来说,update方法就是更新视图的方法,对computed watcher来说,update方法就是立刻执行它的求值回调函数。这样就完成了视图的更新,同时也完成了依赖这个计算属性的别的计算属性的重新求值。当这个计算属性他的subs数组为空(也就是说这个计算属性既没有在页面上显示,也没有被别的计算属性依赖,此时他可能只是当作别的普通函数的变量使用)
此时只会dirty这个flag设置为true,这样别的函数多次引用这个变量时也只会执行一次(缓存优化)