vue源码解读--render函数生成vnode

目录导航

    从之前的分析可以知道,在import vue的时候实际上向vue的原型上添加了诸多的方法,这其中就包括render的定义,分别在src\core\instance\init.js下的initRender,src\core\instance\index.js下的renderMixin

initRender


vue源码解读--render函数生成vnode_第1张图片

    该方法向vue上挂载了两个方法,通过注释可以看出,一个服务于用户手写的render函数,一个则用于template模板

renderMixin

vue源码解读--render函数生成vnode_第2张图片

    向vue原型上挂载了_render方法,该方法在mount的过程中会被调用生成一个vnode实例用于update对比生成一个新的dom对象并对原dom节点进行替换

    该方法将拿到在options上定义的render方法,而render的来源有两种,一种是用户自定义的,形如


vue源码解读--render函数生成vnode_第3张图片

    一种则是使用的template方式,但是该方法最终在mount的过程中通过调用compileToFunctions会被转化render函数,也就是说,最终供_render方法使用的实际上就是我们自定义的render函数


    vm._renderProxy是在init过程中在生产环境下通过es6的proxy api代理的vue实例;实际上就是vue

    vm.$createElement则是在initRender的时候向vue添加的方法,该方法对应的就是手写render函数时的参数createElement函数

    因此,它的参数大概是这样的


vue源码解读--render函数生成vnode_第4张图片

接着就会进行一系列的判断,其中比较关键的是


vue源码解读--render函数生成vnode_第5张图片

        ALWAYS_NORMALIZE在用户手写render时恒为true,因此会走normalizeChildren,并将'hello'作为参数传递


vue源码解读--render函数生成vnode_第6张图片

        由于hello是基础类型,符合isPrimitive为true

        因此将调用createTextVNode生产一个文本vnode


vue源码解读--render函数生成vnode_第7张图片

            因此children得到的就是一个长度为1,值为Vnode的数组

代码向下


vue源码解读--render函数生成vnode_第8张图片

div是平台的保留标签,走进if,调用new VNode生成一个Vnode

入参为


生成的vnode即为render.call的返回值


vue源码解读--render函数生成vnode_第9张图片


也是render函数的返回值



那么,如果我们传入的是一个子组件,vue又会如何处理呢(组件的vnode化)

你可能感兴趣的:(vue源码解读--render函数生成vnode)