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.$destroy
The 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.$destroy
logic
- The trigger
beforeDestroy
hook - remove
Vue
A reference to this component instance in the component chain - Notify each subscription center to remove this from each subscription list
watcher
The subscription - remove
data
The object’s__ob__
- perform
vm.__patch__(vm._vnode, null)
That is, the component instance is destroyed, which is executed on the component instanceinvokeDestroyHook
- The trigger
destroyed
hook - Removes events on component instances
- Removes the component instance
$el
Instance reference of - Of the component node
parent
reference
Global life cycle
vue beforeUpdate -> App two beforeDestroy -> Child beforeDestroy -> Child destroyed -> App two destroyed -> vue updated
The summary of this chapter
- This chapter describes how to uninstall components
destroyed
Phase. - In the update
vnode
When, throughremoveVnodes
Remove this component and execute it internallyremoveAndInvokeRemoveHook
(removedom
),invokeDestroyHook
($destroy
) two methods. - This paper introduces the
Vue.prototype.$destroy
And how to recursively handle the unloading of internal components.