The previous two chapters analyze Vue’s Update phase. In this chapter, we analyze Vue’s Destroyed phase by taking the second App component uninstalled to trigger hide to execute this.isShow = false as an example.

In updateComponent, execute vm._render to get the latest VNode, and then execute vm._update to update the DOM.

In the updateChildren loop, you can see that only the last vnode is different: the old vnode is the App component vnode, and the new vnode is the annotation vnode. Call createElm to create the real DOM from the annotation vNode and insert it into the corresponding position. Then on the next loop of the while, remove the old App component vNodes by removeVnodes.

removeVnodes

function removeVnodes(vnodes, startIdx, endIdx) {
  for (; startIdx <= endIdx; ++startIdx) {
    var ch = vnodes[startIdx];

    if (isDef(ch)) {
      if (isDef(ch.tag)) {
        removeAndInvokeRemoveHook(ch);
        invokeDestroyHook(ch);
      } else {
        // Text noderemoveNode(ch.elm); }}}}Copy the code

The removeVnodes method performs different methods based on the type of vNodes: if it is a tag node, it handles attributes and hooks. If it is a text node, simply remove the DOM.

removeAndInvokeRemoveHook

RemoveAndInvokeRemoveHook methods mainly recursive processing attributes of the child nodes and remove the dom node.

invokeDestroyHook

The invokeDestroyHook invokeDestroyHook triggers the destroy hook of the vNode component, which is analyzed below. Then implement the cbS. destroy and unbindDirectives, and if there are vnod. children, invokeDestroyHook for each recursion. Vue’s Destroyed phase is completed.

componentVNodeHooks.destroy

If the vNode instance is wrapped by a keppAlive component, the deactivateChildComponent is executed to change the state and trigger the Deactivated hook. If not, the component instance’s $destroy method is executed.

Vue.prototype.$destroy

Vue.prototype.$destroyThe source code

  Vue.prototype.$destroy = function () {
    var vm = this;

    if (vm._isBeingDestroyed) {
      return;
    }

    callHook(vm, 'beforeDestroy');
    vm._isBeingDestroyed = true; // remove self from parent

    var parent = vm.$parent;

    if(parent && ! parent._isBeingDestroyed && ! vm.$options.abstract) { remove(parent.$children, vm); }// teardown watchers


    if (vm._watcher) {
      vm._watcher.teardown();
    }

    var i = vm._watchers.length;

    while (i--) {
      vm._watchers[i].teardown();
    } // remove reference from data ob
    // frozen object may not have observer.


    if (vm._data.__ob__) {
      vm._data.__ob__.vmCount--;
    } // call the last hook...


    vm._isDestroyed = true; // invoke destroy hooks on current rendered tree

    vm.__patch__(vm._vnode, null); // fire destroyed hook


    callHook(vm, 'destroyed'); // turn off all instance listeners.

    vm.$off(); // remove __vue__ reference

    if (vm.$el) {
      vm.$el.__vue__ = null;
    } // release circular reference (#6759)


    if (vm.$vnode) {
      vm.$vnode.parent = null; }}; }Copy the code

Vue.prototype.$destroylogic

  1. The triggerbeforeDestroyhook
  2. removeVueA reference to this component instance in the component chain
  3. Notify each subscription center to remove this from each subscription listwatcherThe subscription
  4. removedataThe object’s__ob__
  5. performvm.__patch__(vm._vnode, null)That is, the component instance is destroyed, which is executed on the component instanceinvokeDestroyHook
  6. The triggerdestroyedhook
  7. Removes events on component instances
  8. Removes the component instance$elInstance reference of
  9. Of the component nodeparentreference

Global life cycle

vue beforeUpdate -> App two beforeDestroy -> Child beforeDestroy -> Child destroyed -> App two destroyed -> vue updated

The summary of this chapter

  1. This chapter describes how to uninstall componentsdestroyedPhase.
  2. In the updatevnodeWhen, throughremoveVnodesRemove this component and execute it internallyremoveAndInvokeRemoveHook(removedom),invokeDestroyHook($destroy) two methods.
  3. This paper introduces theVue.prototype.$destroyAnd how to recursively handle the unloading of internal components.