🥕 keep-alive function
keep-live
component is an internal component of vue, mainly used to cache internal component instances. The purpose of this is to keep-alive internal component switching without the need to re-create component instances. For example, use v-if to determine which component to use under what conditions, and route switching. There is a <router-view></router-view>
, which will be based on The routing configuration will select one of the components to render to this location. When the routing is switched, the current component will be destroyed, and it will render another component.
If you nest keep-alive in the outermost layer, like this:
<keepAlive>
<Component1 v-if="xxx"/>
<Component2 v-else-if="xxx"/>
<Component1 v-else/>
</KeepAlive>
In this way, keepAlive
the components inside 060b7176a39c00 switch back and forth, there is no need to recreate the component instance, but directly use the instance in the cache. On the one hand, it can avoid the efficiency overhead caused by creating the component, and on the other hand, it can preserve the state of the component. But at the same time, there is a downside, that is, when the component contains a large amount of content, it will take up more memory space. KeepAlive is equivalent to space for time.
keepAlive
has include
and exclude
attributes, these two attributes determine which components can enter the cache. There is also a max
attribute, through which you can set the maximum number of caches. When the number of cached instances exceeds the set number, Vue will remove the component cache that has not been used for the longest time.
Affected by keep-alive, all nested components inside have two life cycle hook functions, namely activated
and deactivated
, which are triggered when the component is activated and deactivated respectively. The first activated trigger is after mounted
🌻 keep-alive principle
In terms of specific implementation, keep-alive maintains a key array and a cache object internally
//keep-alive 内部声明周期函数
created () {
this.cache = Object.create(null)
this.keys = []
},
The key array records the key value of the component currently cached. If the component does not specify a key value, a unique key value will be automatically generated
The cache object will use the key value as the key and vnode as the value to cache the virtual DOM corresponding to the component
In the keep-alive rendering function, the basic logic is to determine whether the currently rendered vnode has a corresponding cache. If so, the corresponding component instance will be read from the cache, and if not, it will be cached.
When the number of buffers exceeds max
numerical settings, keep-alive
removes the first element in the key array
render () {
const slot = this.$slots.default; //获取默认插槽
const vnode = getFirstComponentChild(slot); //得到插槽中第一个组件的vnode
const name = getComponentName(vnode.componentOptions); //获取组件名字
const { cache, keys } = this; //获取当前的混村内对象和key数组
const key: ?string = vnode.key == null
? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
: vnode.key; //获取组件的key值,如果没有key值,会按照规则自动生成
if (cache[key]) {
//有缓存
//重用组件实例
vnode.componentInstance = cache[key].componentInstance
remove(keys, key); //删除key值
//将key值加入到数组末尾,这样是为了保证最近使用的组件在数组中靠后,主要是为了方便设置的max值删除很久没使用的组件
keys.push(key)
} else {
//没有缓存的则进行缓存
cache[key] = vnode
keys.push(key)
// prune oldest entry
if (this.max && keys.length > parseInt(this.max)) {
//超过最大缓存数量,移除第一个key对应的缓存
pruneCacheEntry(cache, keys[0], keys, this._vnode)
}
}
vnode.data.keepAlive = true
}
return vnode || (slot && slot[0])
}
😊 Alright, the above is my sharing, welcome everyone to discuss duck in the comment area~
I hope my friends will like it👍 and support it~ 😘, I will be more motivated🤞
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。