ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-04-12 13:52:03  阅读:208  来源: 互联网

标签:vue 函数 render DOM alive vnode 组件 keep keepalive


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


图片


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


图片


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

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

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


图片


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


图片


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


图片


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


图片


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


图片


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


图片


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


图片


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


图片


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


图片


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


图片


之后退出createElm函数:


图片


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


图片


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


图片


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


图片


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


图片


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


图片


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


图片


标签:vue,函数,render,DOM,alive,vnode,组件,keep,keepalive
来源: https://blog.51cto.com/u_15127544/2701175

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有