做网站用多大的画布,医疗类网站,建设一个网络交友的网站的论文,郑州小程序开发制作公司文章目录 1. 前言2. 销毁阶段分析3. 总结 1. 前言
接下来到了生命周期流程的最后一个阶段——销毁阶段。从官方文档给出的生命周期流程图中可以看到#xff0c;当调用了vm.$destroy方法#xff0c;Vue实例就进入了销毁阶段#xff0c;该阶段所做的主要工作是将当前的Vue实例… 文章目录 1. 前言2. 销毁阶段分析3. 总结 1. 前言
接下来到了生命周期流程的最后一个阶段——销毁阶段。从官方文档给出的生命周期流程图中可以看到当调用了vm.$destroy方法Vue实例就进入了销毁阶段该阶段所做的主要工作是将当前的Vue实例从其父级实例中删除取消当前实例上的所有依赖追踪并且移除实例上的所有事件监听器。也就是说当这个阶段完成之后当前的Vue实例的整个生命流程就全部走完了最终“寿终正寝”了。 本篇文章就来分析一下在销毁阶段都做了哪些工作。
2. 销毁阶段分析
上文说了当调用了实例的$destroy方法之后当前实例就进入了销毁阶段。所以分析销毁阶段就是分析$destroy方法的内部实现。该方法的定义位于源码的src/core/instance.lifecycle.js中如下
Vue.prototype.$destroy function () {const vm: Component thisif (vm._isBeingDestroyed) {return}callHook(vm, beforeDestroy)vm._isBeingDestroyed true// remove self from parentconst parent vm.$parentif (parent !parent._isBeingDestroyed !vm.$options.abstract) {remove(parent.$children, vm)}// teardown watchersif (vm._watcher) {vm._watcher.teardown()}let i vm._watchers.lengthwhile (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 treevm.__patch__(vm._vnode, null)// fire destroyed hookcallHook(vm, destroyed)// turn off all instance listeners.vm.$off()// remove __vue__ referenceif (vm.$el) {vm.$el.__vue__ null}// release circular reference (##6759)if (vm.$vnode) {vm.$vnode.parent null}
}可以看到在上述代码中首先判断当前实例的_isBeingDestroyed属性是否为true因为该属性标志着当前实例是否处于正在被销毁的状态如果它为true则直接return退出函数防止反复执行销毁逻辑。如下
const vm: Component this
if (vm._isBeingDestroyed) {return
}接着触发生命周期钩子函数beforeDestroy该钩子函数的调用标志着当前实例正式开始销毁。如下
callHook(vm, beforeDestroy)接下来就进入了当前实例销毁的真正逻辑。
首先需要将当前的Vue实例从其父级实例中删除如下
const parent vm.$parent
if (parent !parent._isBeingDestroyed !vm.$options.abstract) {remove(parent.$children, vm)
}上面代码表示如果当前实例有父级实例同时该父级实例没有被销毁并且不是抽象组件那么就将当前实例从其父级实例的$children属性中删除即将自己从父级实例的子实例列表中删除。
把自己从父级实例的子实例列表中删除之后接下来就开始将自己身上的依赖追踪和事件监听移除。
我们知道 实例身上的依赖包含两部分一部分是实例自身依赖其他数据需要将实例自身从其他数据的依赖列表中删除另一部分是实例内的数据对其他数据的依赖如用户使用$watch创建的依赖也需要从其他数据的依赖列表中删除实例内数据。所以删除依赖的时候需要将这两部分依赖都删除掉。如下
// teardown watchers
if (vm._watcher) {vm._watcher.teardown()
}
let i vm._watchers.length
while (i--) {vm._watchers[i].teardown()
}在上述代码中首先执行vm._watcher.teardown()将实例自身从其他数据的依赖列表中删除teardown方法的作用是从所有依赖向的Dep列表中将自己删除。然后在前面文章介绍initState函数时我们知道所有实例内的数据对其他数据的依赖都会存放在实例的_watchers属性中所以我们只需遍历_watchers将其中的每一个watcher都调用teardown方法从而实现移除实例内数据对其他数据的依赖。
接下来移除实例内响应式数据的引用、给当前实例上添加_isDestroyed属性来表示当前实例已经被销毁同时将实例的VNode树设置为null如下
if (vm._data.__ob__) {vm._data.__ob__.vmCount--
}
vm._isDestroyed true
vm.__patch__(vm._vnode, null)接着触发生命周期钩子函数destroyed如下
callHook(vm, destroyed)最后调用实例的vm.$off方法关于该方法在后面介绍实例方法时会详细介绍移除实例上的所有事件监听器。如下
vm.$off()最后再移除一些相关属性的引用至此当前实例算是销毁完毕。
3. 总结
本篇文章介绍了生命周期流程的最后一个阶段——销毁阶段。
我们知道了当调用了实例上的vm.$destory方法后实例就进入了销毁阶段在该阶段所做的主要工作是将当前的Vue实例从其父级实例中删除取消当前实例上的所有依赖追踪并且移除实例上的所有事件监听器。并且对照源码将所做的工作都进行了逐行分析。