1、computed是如何初始化之后干了些什么
//空函数 const noop = ()=>{} // computed初始化的Watcher传入lazy: true就会触发Watcher中的dirty值为true const computedWatcherOptions = { lazy: true } //Object.defineProperty 默认value参数 const sharedPropertyDefinition = { enumerable: true, configurable: true, get: noop, set: noop }
initComputed类 初始化computed
1)constructor中
const userDef = computed[key];
新建存储watcher的对象,,挂载在vm对象执行
遍历computed,给computed中的每一个key都添加watcher
如果计算属性的key不是vm中的,则调用defineComputed将key挂载到vm上,
2)defineComputed
把计算属性的key挂载到vm对象下,并使用object.defineProperty进行处理
在defineComputed中,首先判断 userDef是不是函数
是函数----sharedPropertyDefinition的get为createComputedGetter(key),set为noop(空函数)
不是函数----sharedPropertyDefinition的get 和set方法 如果userDef存在对应的get和set就可以赋值,不存在就直接赋值为空函数
其中get存在缓存的情况,我们需要在userDef.get存在之后还需要判断userDef.cache是否存在,存在就调用createComputedGetter(key)
3)createComputedGetter(key)
计算属性的getter 获取计算属性的值时会调用
函数中return一个函数,首先获取相应的watcher(所以是一个闭包)
如果watcher存在
watcher.dirty(决定了计算属性是否需要重新计算,默认值为true)存在,每次执行之后dirty都会设置为false,只有依赖的值改变才会触发dirty为true,从而获取值时重新计算(watcher.evaluate())
Dep.target存在,就获取也是收集依赖,watcher.depend()
最后返回计算属性的值,return watcher.value
evaluate () { // 调用 get 函数求值 this.value = this.get() // 把 dirty 标记为 false this.dirty = false }
2、为何触发data值改变时computed会从新计算
只有计算属性依赖的响应式值发生更新的时候
3、computed值为什么说是被缓存的呢,如何做的
关键在于dirty属性,只有当dirty为true的时候,才会去计算值,而且每次计算值之后,dirty都会重置为false
发现
dirty
是false了,直接就返回watcher.value
这个值,这其实就是计算属性缓存的概念。