// src/core/components/keep-alive.js
const slot = this.$slots.default
const vnode: VNode = getFirstComponentChild(slot) // 找到第一个子组件对象
const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
if (componentOptions) { // 存在组件参数
const name: ?string = getComponentName(componentOptions) // 组件名
const { include, exclude } = this
(include && (!name || !matches(include, name))) ||
(exclude && name && matches(exclude, name))
const { cache, keys } = this
const key: ?string = vnode.key == null // 定义组件的缓存key
// same constructor may get registered as different local components
// so cid alone is not enough (#3269)
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
if (cache[key]) { // 已经缓存过该组件
vnode.componentInstance = cache[key].componentInstance
// make current key freshest
keys.push(key) // 调整key排序
cache[key] = vnode // 缓存组件对象
if (this.max && keys.length > parseInt(this.max)) { // 超过缓存数限制,将第一个删除
pruneCacheEntry(cache, keys[0], keys, this._vnode)
vnode.data.keepAlive = true // 渲染和执行被包裹组件的钩子函数需要用到
return vnode || (slot && slot[0])