Vue的生命周期及其相应的三个阶段解读
1、生命周期的概念:
vue中的生命周期指的是 组件 从创建到销毁一个过程,在这个过程中,我们在每一个特定的阶段会触发一些方法( 这些方法具备一些功能),我们给这些方法起了个名字叫做 生命周期钩子函数(组件钩子 )。
2、为什么要学习生命周期?
因为我们想在生命周期钩子中实现项目功能,那么我们必须知道每一个钩子函数的具体用途。
3、Vue生命周期的三个阶段:
Vue的生命周期分为三个阶段,分别为: 初始化,运行中 和 销毁,一共8个钩子函数。
注意: 生命周期钩子函数不允许写成箭头函数,因为这里使用箭头函数就会改变this的指向
-------------------------- 1初始化------------------------------
beforeCreate
-
组件创建前触发,目的是为了组件的生命周期 和 组件中的事件做准备
-
数据没有获得,真实dom也没有渲染出来
-
可以进行数据请求,提供了一次数据修改的机会
-
执行一次
created
-
组件创建结束,任务是数据注入和反应
-
数据得到了(如果修改了数据,这里得到的也是旧数据),真实dom没有渲染出来
-
可以进行数据请求,提供了一次数据修改的机会
-
执行了一次
beforeMount
-
组件挂载前
-
** 任务**: 判断el 和 template
如果el没有,那么我们需要手动挂载new Vue().$mount(’#app’),如果有,那么判断template
如果template有,那么进行render函数,将template即jsx转成vdom
如果template没有,那么通过 outerHTML 手动书写模板 -
数据可以获得(旧数据),但是真实dom还没有渲染
-
可以进行数据请求,也提供了一次数据修改的机会
-
执行一次
mounted
-
组件挂载结束,任务是将vdom渲染成真实dom,然后挂载到页面
-
数据获得了(旧数据),真实dom也获得了
-
可以进行数据请求,也可以修改数据
-
执行了一次
-
可以进行真实dom的操作了( 可以进行第三方库静态数据的实例化了 )
综上总结:
-
数据请求一般写在created里面(因为这里第一次得到数据)
-
第三方库实例化我们一般会往mounted中写(静态的数据)
业务: 动态数据请求,然后进行第三方库实例化的优化,将动态数据的第三方库实例化放在updated中是有弊端的,弊端是第三方库会重复实例化
解决:
- 加判断条件
if( this.mySwiper ) return false
- 将实例化放到异步队列中去
- 将实例化放在created的数据请求中,然后放在setTimeout中
- vue提供了一个它认为是最好的方案: nextTick
使用: Vue.nextTick this.$nextTick
nextTick表示组件渲染结束之后这个方法才会调用
-------------------------- 2运行中------------------------------
触发条件:数据更新
beforeUpdate
-
更新前
-
任务是重新渲染 VDOM , 然后通过diff算法比较两次vdom,生成patch 补丁对象
-
这个钩子函数更多的是内部进行一些操作,我们就不再多干预了
-
可以触发多次
updated
-
更新结束,任务是将patch对象渲染成真实dom
-
真实dom得到了,数据也得到了( 更新后的新数据)
-
动态数据获取( 第三方库实例化 )
-------------------------- 3销毁------------------------------
Vue的销毁有两种形式
-
通过开关的形式
-
通过调用 $destroy 方法(这种还需要手动销毁dom外壳)
-------------------- vue生命周期的销毁阶段 -------------------
触发条件: 当组件销毁时:
beforeDestroy
destroyed
这两个钩子功能一致的,这两个钩子没有太大的区别
作用:
用来做善后的,比如计时器的关闭、第三方实例的删除
Vue的销毁有两种形式
- 通过开关的形式 - 外部销毁
- 通过调用 $destroy 方法 - 内部销毁
对比: 内部销毁 vs 外部销毁
外部销毁不仅能销毁组件,也能销毁该组件的dom结构
内部销毁只能销毁组件,不能销毁组件的dom结构 需手动销毁
vue生命周期的钩子
1.根组件实例:8个钩子 (beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)
2.组件实例:8个 (beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)
3.全局路由钩子:2个 (beforeEach、afterEach)
4.组件路由钩子:3个 (beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave)
5.指令的周期: 5个 (bind、inserted、update、componentUpdated、unbind)
6.beforeRouteEnter的next所对应的周期
7.nextTick所对应的周期
Vue提供的可以注册的钩子都在上图片的红色框标注。
beforeCreate
在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
created
实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount
在挂载开始之前被调用:相关的 render 函数首次被调用。
mounted
el 被新创建的 vm.el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当mounted被调用时vm.el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当mounted被调用时vm.el 也在文档内。
beforeUpdate
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
该钩子在服务器端渲染期间不被调用。
beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。