In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
Most people do not understand the knowledge points of this article "what is the principle of the implementation of Vue keep-alive?", so the editor summarizes the following, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "what is the principle of the implementation of Vue keep-alive" article.
The realization principle of keep-alive
When using vue, everyone must have used keep-alive, which is used to cache the page and its state. After using vue for such a long time, I only know how to use it but I don't understand how it works. Yesterday, I looked at the implementation code and made a note here.
Take vue3 as an example.
The source code of the entire component is:
Const KeepAliveImpl = {name: `KeepAlive`, / / Marker for special handling inside the renderer. We are not using a = / / check directly on KeepAlive in the renderer, because importing it directly / / would prevent it from being tree-shaken. _ _ isKeepAlive: true, props: {include: [String, RegExp, Array], exclude: [String, RegExp, Array], max: [String, Number]}, setup (props: KeepAliveProps, {slots}: SetupContext) {const cache: Cache = new Map () const keys: Keys = new Set () let current: VNode | null = null const instance = getCurrentInstance ()! / / console.log ('instance' Instance) / / KeepAlive communicates with the instantiated renderer via the "sink" / / where the renderer passes in platform-specific functions, and the / / KeepAlive instance exposes activate/deactivate implementations. / / The whole point of this is to avoid importing KeepAlive directly in the / / renderer to facilitate tree-shaking. Const sink = instance.sink as KeepAliveSink const {renderer: {move, unmount: _ unmount, options: {createElement}}, parentSuspense} = sink const storageContainer = createElement ('div') / / console.log (' sink',sink) sink.activate = (vnode, container, anchor) = > {move (vnode, container, anchor, MoveType.ENTER) ParentSuspense) queuePostRenderEffect (() = > {const component = vnode.component! Component.isDeactivated = false if (component.a! = = null) {invokeHooks (component.a)}}, parentSuspense)} sink.deactivate = (vnode: VNode) = > {move (vnode, storageContainer, null, MoveType.LEAVE, parentSuspense) queuePostRenderEffect () = > {const component = vnode.component! If (component.da! = = null) {invokeHooks (component.da)} component.isDeactivated = true}, parentSuspense)} function unmount (vnode: VNode) {/ / reset the shapeFlag so it can be properly unmounted vnode.shapeFlag = ShapeFlags.STATEFUL_COMPONENT _ unmount (vnode, instance, parentSuspense)} function pruneCache (filter?: (name: string) = > boolean) {cache.forEach (vnode Key) = > {const name = getName (vnode.type as Component) if (name & & (! filter | |! filter (name)) {pruneCacheEntry (key)}})} function pruneCacheEntry (key: CacheKey) {const cached = cache.get (key) as VNode if (! current | | cached.type! = current.type) {unmount (cached)} else If (current) {/ / current active instance should no longer be kept-alive. / / we can't unmount it now but it might be later, so reset its flag now. Current.shapeFlag = ShapeFlags.STATEFUL_COMPONENT} cache.delete (key) keys.delete (key)} watch (() = > [props.include, props.exclude], ([include, exclude]) = > {include & & pruneCache (name = > matches (include, name) exclude & & pruneCache (name = > matches (exclude, name))} {lazy: true}) onBeforeUnmount (() = > {cache.forEach (unmount)}) return () = > {if (! slots.default) {return null} const children = slots.default () let vnode = children [0] if (children.length > 1) {if (_ _ DEV__) {warn (`KeepAlive should contain exactly) One component child.`)} current = null return children} else if (! isVNode (vnode) | |! (vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT)) {current = null return vnode} const comp = vnode.type as Component const name = getName (comp) const {include Exclude, max} = props if ((include & & (! name | |! matches (include, name) | | (exclude & & name & & matches (exclude, name) {return vnode} const key = vnode.key = = null? Comp: vnode.key const cached = cache.get (key) / / clone vnode if it's reused because we are going to mutate it if (vnode.el) {vnode = cloneVNode (vnode)} cache.set (key Vnode) if (cached) {/ / copy over mounted state vnode.el = cached.el vnode.anchor = cached.anchor vnode.component = cached.component if (vnode.transition) {/ / recursively update transition hooks on subTree setTransitionHooks (vnode) Vnode.transition!)} / / avoid vnode being mounted as fresh vnode.shapeFlag | = ShapeFlags.COMPONENT_KEPT_ALIVE / / make this key the freshest keys.delete (key) keys.add (key)} else {keys.add (key) / / prune oldest entry if (max & & keys.size > parseInt (max as string) 10)) {pruneCacheEntry (Array.from (keys) [0])}} / / avoid vnode being unmounted vnode.shapeFlag | = ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE current = vnode return vnode}
It's easy to see that keep-alive is actually a component encapsulated by vue itself, just like a normal component.
Before moving on to the keep-alive component, let's take a look at the whole rendering of the vue component.
The general process is as follows
Keep-alive lifecycle
Component mount:
Call the setupStatefulComponent function to trigger the setup method of the component, in which the core code of the setup method of the component is actually a few lines:
Return () = > {const children = slots.default () let vnode = children [0] cache.set (key, vnode) if (cached) {vnode.el = cached.el vnode.anchor = cached.anchor vnode.component = cached.component vnode.shapeFlag | = ShapeFlags.COMPONENT_KEPT_ALIVE keys.delete (key) keys.add (key)} else {keys.add (key)} return vnode}
The main logic is as follows:
1. Confirm the slot to be rendered,
two。 Put its state in the cache or read an existing cache,
3. Return the vnode corresponding to slot, and then call setupRenderEffect to render the dom.
Component updates (slot changes):
When the slot changes, the render of the keep-alive component, that is, the return function of setup, is first called. The logic is shown in the setup method above. Then, when a slot is unloaded, the deactivate function is called, and when a slot is remounted, the activate function is called. The core code is as follows:
Const storageContainer = createElement ('div') sink.activate = (vnode, container, anchor) = > {move (vnode, container, anchor, MoveType.ENTER, parentSuspense) queuePostRenderEffect (() = > {const component = vnode.component! Component.isDeactivated = false if (component.a! = = null) {invokeHooks (component.a)}}, parentSuspense)} sink.deactivate = (vnode: VNode) = > {move (vnode, storageContainer, null, MoveType.LEAVE, parentSuspense) queuePostRenderEffect () = > {const component = vnode.component! If (component.da! = = null) {invokeHooks (component.da)} component.isDeactivated = true}, parentSuspense)}
The logic is also simple: when the component is unloaded, it is moved into the cached dom node, the slot's deactivate life cycle is called, and when the component is remounted, it is moved to the mounted dom node.
To sum up, the principle of keep-alive implementation is to put the corresponding state into a cache object and the corresponding dom node into the cache dom. When you need to render again, get the state from the object and move it from the cache dom to the mount dom node.
Summary of the use of keep-alive
In normal development, some components only need to be loaded once, and the subsequent data will not change, or the components need to cache state, scroll bar location, and so on. At this time, the usefulness of keep-alive is immediately highlighted.
Using keep-alive in 1.App.vue
Include means pages that need to be cached, and exclude means pages that do not need to be cached. You can set only one of them, but when you set both, keep in mind that exclude takes precedence over include. For example, component an exists in both exclude and include, so component a will not be cached.
Export default {name: 'App', data () {return {isRouterAlive:true, whiteList: [' styleLibrary','OrderList','SalesData'], blackList: ['Footer'], personShow:false,}},} 2.App.vue for use with router
Set the keepAlive in the $route.meta of the component that needs to be cached to true and vice versa to false
{path:'/login', name:'login', component:resolve= > require (['@ / pages/login'], resolve), meta: {keepAlive:true, title:' login', savedPosition:true,}}. These are the contents of this article on "what is the implementation principle of Vue keep-alive". I believe everyone has a certain understanding. I hope the content shared by the editor will be helpful to all of you. If you want to know more about the relevant knowledge, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.