When switching between components, sometimes you want to maintain the state of these components to avoid performance issues caused by repeated re-rendering. When wrapping dynamic components with <keep-alive>
, inactive component instances will be cached instead of destroyed.
Recreating dynamic components is often very useful, but in some cases we prefer to cache instances of those components when they are first created. In this case, wrapping the component with <keep-alive>
can cache the current component instance, storing the component in memory for preserving its state or avoiding re-rendering. Similar to <transition>
, it does not render a DOM
element itself and does not appear in the parent component chain.
Components contained within <keep-alive>
will not be reinitialized, meaning that their lifecycle hooks will not be triggered again. <keep-alive>
maintains the current component's state and will trigger its creation lifecycle normally the first time it is created. However, since the component is not actually destroyed, the destruction lifecycle of the component will not be triggered. When the component is toggled within <keep-alive>
, its activated
and deactivated
lifecycle hooks will be executed accordingly.
<keep-alive>
can receive 3
attributes as parameters to match corresponding components for caching. First, it checks the component's own name
option. If the name
option is not available, it matches its locally registered name, which is the key of the parent component's components
option. Anonymous components cannot be matched. In addition to using <keep-alive>
's props
to control component caching, it is usually combined with the meta
property defined in vue-router
and the <keep-alive>
defined in the template
for conditional caching control of components.
include
: Components to be included, which can be a string, array, or regular expression. Only the matched components will be cached.exclude
: Components to be excluded, which can be a string, array, or regular expression. No matched components will be cached. When matching conditions exist in both include
and exclude
, exclude
takes the highest priority.max
: The maximum number of cached components, which can be a string or number. It controls the number of cached components. Once this number is reached, the least recently accessed instance among the cached components will be destroyed before a new instance is created.<keep-alive>
is used in a scenario where one of its immediate child components is being toggled. If there is a v-for
inside, it will not work. If there are multiple conditional child elements as described above, <keep-alive>
requires that only one child element is rendered at the same time. In simple terms, <keep-alive>
can only have one child component at most, and in the render
function of <keep-alive>
, when rendering the components within <keep-alive>
, Vue
takes the first immediate child component for caching.
The source code of the <keep-alive>
component in Vue
is defined in dev/src/core/components/keep-alive.js
. The commit id
for this analysis implementation is 215f877
.
During the initialization of <keep-alive>
, in the created
phase, two variables are initialized: cache
and keys
. In the mounted
phase, the values of the include
and exclude
variables are monitored.
The $watch
method above can detect changes in parameters. If the values of include
or exclude
change, the pruneCache
function is triggered. However, the filtering conditions need to be determined based on the return value of the matches
function. The matches
function accepts three types of parameters: string
, RegExp
, and Array
, to determine whether caching should occur.
The pruneCache
function is used to prune the key
values that do not meet the conditions. Whenever the filter condition changes, the pruneCacheEntry
method must be called to prune the key
that does not meet the conditions from the existing cache.
During each rendering or render
, the first child component is obtained first, followed by obtaining the configuration information of the child component. Its information is obtained, and it is determined whether the component meets the filtering conditions before rendering. If it does not need to be cached, the component is directly returned. If it meets the conditions, the instance of the component is directly taken from the cache, and its position in the keys
array is adjusted to place it at the end. If the component is not in the cache, it is added to the cache. If max
is defined, and the number of cached components exceeds the value defined by max
, the first cached vnode
is removed. Then the component is returned and rendered.