从之前的分析可以知道,在import vue的时候实际上向vue的原型上添加了诸多的方法,这其中就包括render的定义,分别在src\core\instance\init.js下的initRender,src\core\instance\index.js下的renderMixin
initRender
该方法向vue上挂载了两个方法,通过注释可以看出,一个服务于用户手写的render函数,一个则用于template模板
renderMixin
向vue原型上挂载了_render方法,该方法在mount的过程中会被调用生成一个vnode实例用于update对比生成一个新的dom对象并对原dom节点进行替换
该方法将拿到在options上定义的render方法,而render的来源有两种,一种是用户自定义的,形如
一种则是使用的template方式,但是该方法最终在mount的过程中通过调用compileToFunctions会被转化render函数,也就是说,最终供_render方法使用的实际上就是我们自定义的render函数
vm._renderProxy是在init过程中在生产环境下通过es6的proxy api代理的vue实例;实际上就是vue
vm.$createElement则是在initRender的时候向vue添加的方法,该方法对应的就是手写render函数时的参数createElement函数
因此,它的参数大概是这样的
接着就会进行一系列的判断,其中比较关键的是
ALWAYS_NORMALIZE在用户手写render时恒为true,因此会走normalizeChildren,并将'hello'作为参数传递
由于hello是基础类型,符合isPrimitive为true
因此将调用createTextVNode生产一个文本vnode
因此children得到的就是一个长度为1,值为Vnode的数组
代码向下
div是平台的保留标签,走进if,调用new VNode生成一个Vnode
入参为
生成的vnode即为render.call的返回值
也是render函数的返回值
那么,如果我们传入的是一个子组件,vue又会如何处理呢(组件的vnode化)
网友评论