π₯ keep – the alive
The Keep-live component is an internal component of vUE and is mainly used to cache internal component instances. For example, v-if is used to determine which component to use under what conditions. There is also a route switch.
If keep-alive is nested on the outermost layer, it looks like this:
<keepAlive>
<Component1 v-if="xxx"/>
<Component2 v-else-if="xxx"/>
<Component1 v-else/>
</KeepAlive>
Copy the code
In this way, when components inside keepAlive switch back and forth, they do not need to recreate the component instance. Instead, they directly use the instance in the cache. On the one hand, the efficiency cost of creating components can be avoided, and on the other hand, the state of components can be preserved. The downside of keepAlive is that it takes up a lot of memory when a component contains a lot of content. KeepAlive is a space-for-time approach.
KeepAlive has include and exclude attributes, which determine which components can be cached. There is also a Max attribute that allows you to set the maximum number of caches, and when the number of cached instances exceeds the set number, vUE removes the longest unused component cache.
Under the influence of keep-Alive, all nested components have two lifecycle hook functions: Activated and deactivated. The hook functions activated and deactivated are triggered when a component is activated and deactivated respectively. The first value of activated is triggered after Mounted
π» keep alive – principle
In its implementation, keep-Alive internally maintains a key array and a cache object
//keep-alive internally declares a periodic function
created () {
this.cache = Object.create(null)
this.keys = []
},
Copy the code
The key array records the component key currently cached. If the component does not specify a key value, a unique key value is automatically generated
The cache object is used to cache the virtual DOM corresponding to the component, with the key as the key and the vNode as the value
In keep-Alive’s 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 caches exceeds the value set by Max, keep-alive removes the first element in the key array
render () {
const slot = this.$slots.default; // Get the default slot
const vnode = getFirstComponentChild(slot); // Get the vNode of the first component in the slot
const name = getComponentName(vnode.componentOptions); // Get the component name
const { cache, keys } = this; // Get the current array of objects and keys
constkey: ? string = vnode.key ==null
? componentOptions.Ctor.cid + (componentOptions.tag ? ` : :${componentOptions.tag}` : ' ')
: vnode.key; // Get the key value of the component. If there is no key value, it will be generated automatically according to the rule
if (cache[key]) {
/ / a cache
// Reuse component instances
vnode.componentInstance = cache[key].componentInstance
remove(keys, key); // Delete the key
// Add the key value to the end of the array to ensure that recently used components are placed later in the array, mainly to facilitate the Max value to delete components that have not been used for a long time
keys.push(key)
} else {
// If there is no cache, cache it
cache[key] = vnode
keys.push(key)
// prune oldest entry
if (this.max && keys.length > parseInt(this.max)) {
// Remove the cache corresponding to the first key when the maximum number of caches is exceeded
pruneCacheEntry(cache, keys[0], keys, this._vnode)
}
}
vnode.data.keepAlive = true
}
return vnode || (slot && slot[0])}Copy the code
π, that’s all I have to say about duck in the comments section
I hope you can like π to support oh ~ π, I will be more motivated π€