Vue源码之响应式原理笔记

141 阅读2分钟

首先initState 两件事:

数据响应式的入口:分别处理propsmethodsdatacomputedwatch

优先级: propsmethodsdatacumputed 对象中的属性不能重复出现,优先级和列出的一致

ps: 其中computed 中的key不能和propsdata中的key重复,methods 不影响。

处理props对象,为props对象的每个属性设置响应式,并将其代理vm实例上

initProps():

首先缓存了props的每个Key,做出性能优化。

接着是遍历对象,缓存key,获取到props[key] 的默认值,再将props的每个key设置数据响应式,最后将key代理到vm对象上。 处理methods对象,校验每个属性的值是否为函数,和props属性进行判重处理,最后得到vm.[key] = methods

initMethods():

首先获取props配置项

接着是遍历methods里的对象

处理data:

做了三件事:

1.判重处理,data对象上属性不能和props,methods对象上的属性形同

2.代理data对象上的属性到vm实例

3.为了data对象上的数据设置响应式

initData():

首先是获取data对象,

接着是判重处理,因为data对象上的属性不能和props,methods对象的属性相同,再将data对象代理到vm实例上。

最后将data对象上的数据设置为响应式 处理computed: 做了三件事:  1.为computed[key] 创建watcher实例,默认是懒执行

2.代理computed[key]到vm实例

3.判重,computed中的key不能和data,props中的属性重复

首先initComputed():

遍历computed对象,获取到key对应的值,getter函数,再为computed属性创建watcher实例,设置配置项,将computed默认是懒执行。接着将computed对象代理到vm实例中,就可以使用vm.computedKey访问计算属性,最后是进行一个非生产环境的判重处理,comtuted对象中的属性不能和data,props中的属性相同。 接着是defineComputed():

首先是构造属描述符(get,set),接着是拦截target.key的访问和设置(Object.defineProperty(target, key, sharedPropertyDefinition ))

接着是createdComutedGetter():

ps:这里应该有个知识点: computed属性值会缓存的原理也是在这里面结合watch.dirty, watcher.evalaute,watcher.update实现

首先要得到当前key对应的watcher。

然后是createGetterInvoker():

功能同createComputedGetter一样。

  处理watch:

做了三件事:

1.处理watch对象

2.为每个watch.key创建watcher实例,key和watcher实例可能是一对多的关系

3.如果设置了immediate,则立即执行回调函数

首先initWatch():

遍历watch对象,其中handler为数组,遍历数组,获取其中的每一项,然后调用createWatcher

接着createdWatcher():

做两件事:

1.兼容性处理,保证handler肯定是一个函数

2.调用$watcher

首先如果handler为对象,则获取其中的handler选项的值

如果handler为字符串,则说明是一个methods方法,获取vm[handler]