文章前提:已经clone下来vue源码
直接进入主题,computed计算属性的初始化位置是在new Vue的时候初始化的。
查看顺序:
1、/src/core/instance/index.js 中的initMixin函数执行中
2、initMixin函数在/src/core/instance/init.js中,函数有调用initState函数(注意初始化是在created生命周期之前)
3、在initState函数中可以看到data、props、methods、computed、watch都在这里初始化的
这里我们就看到initComputed函数了,这个函数的参数为两个,vm为vue实例,computed为我们定义的computed。
我们一步一步来解析
1、初始化一个保存计算属性的空对象
2、判断当前是否是服务端渲染
3、遍历computed的每一个key,获取key对应的value,因为我们在写计算属性是有两个方式的,一种是写一个函数直接返回value(getter函数),另一种是我们去自定义get、set属性,所以这里会判断value是否为函数来取getter函数
4、环境判断先不说了
5、在非服务端渲染的时候,vue会为computed中的每一个key创建一个watcher,并保存在第一行初始化的对象中
6、这个vue会判断computed中的key是否已经在实例中定义过,如果未定义的话,则运行defineComputed函数
接下来我们来看一下defineComputed函数
这里截取了两个函数,defineComputed和createComputedGetter两个函数
先说说defineComputed函数,还是离不开get、set属性
1、判断当前是否为服务端渲染,如果为服务端渲染则将计算属性的get、set定义为用户定义get、set;如果非服务端渲染的话则在定义get属性的时候并没有直接赋值用户函数,而是返回一个新的函数computedGetter
2、这里会判断userDef也就是用户定义计算属性key对应的value值是否为函数,如果为函数的话,则将get定义为用户函数,set赋值为一个空函数noop;如果不为函数(对象)则分别取get、set字段赋值
3、在非服务端渲染中计算属性的get属性为computedGetter函数,在每次计算属性触发get属性时,都会从实例的_computedWatchers(在initComputed已初始化)计算属性的watcher对象中获取get函数(用户定义函数)
4、最终会把当前key定义到vue实例上,也就是可以this.computedKey可以获取到的原因
到此计算属性就这样初始化结束了。
emmmm.....第一次写文章,可能语言什么的都不太好,多多包容,如果有什么建议欢迎提出哈,谢谢啦