if (cache[key]) {
vnode.componentInstance = cache[key].componentInstance
remove(keys, key)
keys.push(key)
} else {
cache[key] = vnode
keys.push(key)
if (this.max && keys.length > parseInt(this.max)) {
pruneCacheEntry(cache, keys[0], keys, this._vnode)
}
}
由于keep-alive包裹的组件是Foo组件,根据规则,此时生成的key和第一此渲染Foo组件时生成的key是一样的,所以本次keep-alive的render函数进入到了第一个if分支,也就是匹配到了cache[key],把缓存的componentInstance赋值给当前vnode,然后更新keys(当存在max的时候,能够保证被删除的是比较老的缓存)。
很多同学可能会问,这里设置vnode.componentInstance会有什么作用。这里涉及到vue的源码部分。
由于是从Bar组件切换到Foo组件,所以在patch的时候,比对到此处,并不会被判定为sameVnode,所以自然而然走到createElm,由于Foo是Vue组件,所以会进入到createComponent,所以最终进入到下面函数片段
function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {
var i = vnode.data;
if (isDef(i)) {
var isReactivated = isDef(vnode.componentInstance) && i.keepAlive;
if (isDef(i = i.hook) && isDef(i = i.init)) {
i(vnode, false /* hydrating */);
}
// after calling the init hook, if the vnode is a child component
// it should've created a child instance and mounted it. the child
// component also has set the placeholder vnode's elm.
// in that case we can just return the element and be done.
if (isDef(vnode.componentInstance)) {
initComponent(vnode, insertedVnodeQueue);
insert(parentElm, vnode.elm, refElm);
if (isTrue(isReactivated)) {
reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);
}
return true
}
}
}
可以根据上面对于keep-alive源码的分析,此处isReactivated为true,接下去会进入到vnode生成的时候挂在的生命周期init函数
var componentVNodeHooks = {
init: function init (vnode, hydrating) {
if (
vnode.componentInstance &&
!vnode.componentInstance._isDestroyed &&
vnode.data.keepAlive
) {
// kept-alive components, treat as a patch
var mountedNode = vnode; // work around flow
componentVNodeHooks.prepatch(mountedNode, mountedNode);
} else {
var child = vnode.componentInstance = createComponentInstanceForVnode(
vnode,
activeInstance
);
child.$mount(hydrating ? vnode.elm : undefined, hydrating);
}
},
prepatch: function prepatch (oldVnode, vnode) {
var options = vnode.componentOptions;
var child = vnode.componentInstance = oldVnode.componentInstance;










