通过keep-alive实现了解vue组件实现原理(3)

        然后,VueComponent实例的渲染Watcher再调用updateComponent函数重新render:


通过keep-alive实现了解vue组件实现原理(3)


在$options中取到render函数执行:


通过keep-alive实现了解vue组件实现原理(3)


        下面这个keepalive组件的render函数对于理解keepalive非常重要,在keepalive组件render的时候,先会拿到slot插槽元素,通过getFirstComponentChild函数获取到slot中的第一个元素(组件A)的vnode,获取到第一个元素的componentOptions中的tag,通过keepalive组件中的include和exclude条件判断如果不满足,render函数返回这个第一个子节点的vnode。

        如果可以被缓存,下面会判断cache中是否已经缓存了这个元素,如果缓存过直接取出之前缓存的,如果没有缓存过就加入缓存。

        最后给vnode.data.keepAlive赋值为true,返回vnode。


通过keep-alive实现了解vue组件实现原理(3)


之后在_render函数中给vnode.parent赋值为原来的keepalive的vnode节点,然后返回:


通过keep-alive实现了解vue组件实现原理(3)


之后进入patch函数,注意一下,keepalive组件由于在render阶段返回了它第一个子组件的vnode所以它是没有走patch的,而走了patch的组件A由于没有定义oldVnode,直接执行createElm,而不是像根vue实例一样走最下面的createElm:


通过keep-alive实现了解vue组件实现原理(3)


进入createElm后,再进入createComponent函数:


通过keep-alive实现了解vue组件实现原理(3)


同keepalive组件,组件A也会进入初始化逻辑:


通过keep-alive实现了解vue组件实现原理(3)


但是与keepalive组件不同的是,组件A没有自带的render函数,所以在mount时,会通过compileToFunctions自己通过template模板生成render函数:


通过keep-alive实现了解vue组件实现原理(3)


接下来还是会通过自己的渲染Watcher调用updateComponent来通过render函数生成vnode和渲染到真实DOM上,可以看到patch的时候,vnode根节点的tag已经是div了,即组件A内部的元素节点,而当前所在组件的_uid为2(右下角水印盖住了):


通过keep-alive实现了解vue组件实现原理(3)


在patch中生成了组件A内容的真实DOM后执行insert钩子,然后通过vnode.elm返回真实DOM:


通过keep-alive实现了解vue组件实现原理(3)


在从__patch__中返回的真实DOM被赋值给当前实例(组件A)的$el属性之后,从_update中返回:


通过keep-alive实现了解vue组件实现原理(3)


返回到进入对组件A调用createComponent函数后,又执行了initComponent把新生成的真实DOM挂载到vnode.elm中,并且push到了insertedVnodeQueue数组中:


通过keep-alive实现了解vue组件实现原理(3)


之后退出createElm函数:


通过keep-alive实现了解vue组件实现原理(3)


返回到patch函数中调用了insert钩子,然后返回构建好的组件A的真正DOM:


通过keep-alive实现了解vue组件实现原理(3)


在接着返回到的_update中,组件A的真实DOM被赋值给了组件_uid为1的组件,即为keepalive组件的$el属性,然后返回:


通过keep-alive实现了解vue组件实现原理(3)


然后返回对keepalive组件调用createComponent方法,组件A的真实DOM会被挂载到keepalive组件的父节点中然后返回:


通过keep-alive实现了解vue组件实现原理(3)


接着返回到根组件对三个子组件进行迭代调用createElm的地方:


通过keep-alive实现了解vue组件实现原理(3)


返回到对根节点调用createElm后,通过insert函数,把#app节点的真实DOM插入到页面中的body元素中:


通过keep-alive实现了解vue组件实现原理(3)


退出到patch函数中,通过removeVnodes函数移除了原来的子节点,下图右侧方框中为还没有解析的button节点和keep-alive节点:


通过keep-alive实现了解vue组件实现原理(3)


上一篇:Keep C - 比较两个数 - April 10


下一篇:Android开发实战——代码混淆解决方案,适配AndroidX