摘要:在Vue中组件都有一个render函数,假如你不写,那么Vue就自己动手解析,然后生成一个render函数。但有时候会出现这种情况,我们直接写一个自定义的render函数,那么Vue就不生成了转而使用给出的render,因为render的优先级最高。
提示:后面有完整的调试代码,可以先运行看结果。
这篇文章写的比较深入,需要对Vue有整体的了解。我写下自己的理解,试着把这个问题解释清楚。
下面进入正题。
在Vue中组件都有一个render函数,假如你不写,那么Vue就自己动手解析,然后生成一个render函数。但有时候会出现这种情况,我们直接写一个自定义的render函数,那么Vue就不生成了转而使用给出的render,因为render的优先级最高。
一旦能自定义渲染函数,那么就可以做很多发挥,伪码如下:
//伪码render:function{...//根据条件返回vnode...return vnode}分析:render函数就是返回一个vnode,称为虚拟节点。它也不管我们是咋弄的,所以我们想怎么写都可以,只要最终给它一个结果就可以了。
再看keep-alive,它本质是一个组件。如果我们想了解一个东西,首先看清它是什么,一旦明确了就可以分析。这个组件是Vue内部定义的并且进行了混入,所以就是内部组件可以直接使用。
它是一个抽象组件,意思是说它自己本身没有DOM,而是依靠自己的子组件进行渲染。通俗的说就是,它把子组件渲染了返回给系统。我们看一个具体代码:
....分析:先渲染根实例,往下走,走啊走,就遇到了,发现它是一个组件,于是就生成一个组件实例然后挂载,递归的走了一遍根实例的流程。
但是组件和普通的DOM元素有一个很大的区别在于,组件里面包裹的节点被称为renderChildren,而且只有组件才会有。现在,我们把视角移到keep-alive内部,现在说话的上下文是keep-alive这个组件,这个上下文非常重要。
它开始解析节点,然后将解析出来当做renderChildren,而且还有一个关键的地方,就是在解析过程中绑定了变量isShow,于是产生了依赖收集,但此时的vm实例不是根实例,而是当前的上下文实例,也就是keep-alive组件实例,这就是上下文的重要性。
为什么要强调这个呢?这个在后面会提到,现在先到这里。
renderChildren的作用在前面写slot的那一篇(第8篇)中提到过,是这样写的,就像蛋糕店一样,东西摆出来是筛选的。那么这个renderChildren就是准备替换slot占位符的。
把这个理论搬过来,那么keep-alive包裹的这个节点就是替换slot的,问题是keep-alive哪里有slot定义呢??没有看到,但是keep-alive是把它当做是的,而且是做为default插槽的。
明白了,keep-alive内部的这个renderChildren是做为它的default插槽来使用的,而且只要一个。为什么呢?因为keep-alive的主要思路就是缓存一个组件,要是很多具名slot会和它的设计思路冲突。打个比方说,只有一张椅子可以坐任意一个人,但是椅子只有一个。
写到这里,我们看清楚了keep-alive和它内部包裹的节点究竟是什么了。通俗的说,当要渲染它时,它说自己没有什么可渲染的,把自己的儿子拿出来渲染一下(收集的默认插槽)。
组件收集好slot之后,就进入到keep-alive的render函数,这个render函数是Vue内部定义好的,呼应了最前面介绍的render函数。它比较简单,主要是有一个cache缓存,如下图所示:
在缓存中,通过key来标明某个具体组件,值为该组件的vnode,同时还缓存了对应的组件实例。
当需要某组件的vnode时,从缓存中返回,这就是keep-alive的缓存原理。
当点击按钮隐藏元素时,我们根据前文知道,isShow的渲染上下文实例就是keep-alive组件,然后触发该组件更新,在更新过程中发现包裹的slot已经不在了(v-if=false隐藏了)。
那么就会在keep-alive的render函数中直接返回undefined,渲染结果就为空。
从keep-alive的流程中,就可以看出抽象组件的含义,它没有具体的DOM,只是将自己控制的子组件根据条件进行返回。
一、keep-alive是一个组件,将包裹的节点当做slot,而且是默认插槽。
二、keep-alive在它的render函数中,会缓存该组件vnode,需要时直接从缓存中返回。
{{ isShow ? '隐藏组件' : '显示组件' }}// 只有一个测试组件Vue.component('test-component', {template: `我是测试组件
`});new Vue({el: '#app',data {return {isShow: true // 控制组件显示/隐藏的状态}}});来源:恋爱脑一点号