It all started with the Render method of the KeepAlive component adding a property to the vNode cached in the cache

vnode.data.KeepAlive = true
Copy the code

A vnode with data.keepAlive=true must have components in its keepAlive function when not rendered for the first time. Vue registers several vnodeHooks for each component, which it uses to init the component. Insert and destroy

  • How does data.keepAlive=true affect init
Function init(vnode, hydrating) {// data.keepAlive=true; Mounted if (vnode.componentInstance &&! vnode.componentInstance._isDestroyed && vnode.data.keepAlive ) { // kept-alive components, treat as a patch var mountedNode = vnode; // work around flow componentVNodeHooks.prepatch(mountedNode, mountedNode); } else {// If data.keepAlive=true, child.$mount will not be executed. // So if data.keepAlive=true, Will not trigger this vnode corresponding callHooks (" mounted ") var child ponentInstance = = vnode.com createComponentInstanceForVnode (vnode, activeInstance ); child.$mount(hydrating ? vnode.elm : undefined, hydrating); }},Copy the code
  • See how the destroyed method is affected. How do you trigger the Deactivated hook
destroy: function destroy(vnode) { var componentInstance = vnode.componentInstance; if (! componentInstance._isDestroyed) { if (! vnode.data.keepAlive) { componentInstance.$destroy(); } else {// If there is a data.keepAlive=true property, the deactivateChildComponent method will not be destroyed as if above. The deactivated hook deactivateChildComponent(componentInstance, true /* direct */) is called; } } } function deactivateChildComponent(vm, direct) { ... Omit extraneous code if (! vm._inactive) { // ... Omit irrelevant code callHook(vm, 'deactivated'); }}Copy the code
  • How does that affect the insert method? How do I trigger the Activated hook
insert: function insert(vnode) { var context = vnode.context; var componentInstance = vnode.componentInstance; // ComponentInstance. _isMounted == false componentInstance._isMounted) { componentInstance._isMounted = true; callHook(componentInstance, 'mounted'); } // If (vnode.data.keepalive) {if (context._ismounted) {// if (context._ismounted) {// So here's activatedChildren. Push (VM), pushing componentInstance into an array and storing queueActivatedComponent(componentInstance); } else {// This method calls the activated hook directly,callHook(vm, 'activated'); activateChildComponent(componentInstance, true /* direct */); } } }, function queueActivatedComponent(vm) { vm._inactive = false; // Push componentInstance into an array and store activatedChildren.push(vm); }} function flushSchedulerQueue() {flushSchedulerQueue() {//... Var activatedQueue = activatedChildren.slice(); // activatedChildren is assigned to activatedQueue callActivatedHooks(activatedQueue); // The value of activated in the array is activated. } function callActivatedHooks(queue) {for (var I = 0; i < queue.length; i++) { queue[i]._inactive = true; activateChildComponent(queue[i], true /* true */); Function activateChildComponent(vm, direct) {//... Omit unrelated to code the if (vm) _inactive | | vm. _inactive = = = null) {/ /... Omit irrelevant code callHook(vm, 'activated'); }}Copy the code