生命周期示意图:
生命周期及其钩子函数理解
生命周期: Vue是一个构造函数,当执行执行这个函数时,相当于初始化vue实例;在创建实例过程中,需要设置数据监听,编译模板,将实例挂载到DOM上,数据更新能够让DOM也更新,同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
生命周期钩子函数:
生命周期钩子函数,让够让咱们在初始化实例时,添加自己的代码;
生命周期的钩子函数中的this,会默认指向vue的实例;
钩子函数汇总:
beforeCreate:是第一个生命周期函数,表示实例完全被创建出来之前会执行这个函数。在此函数执行时,data和methods中的属性与方法定义都还没有初始化。
created:是第一个生命周期函数,在此函数中,data 和 methods 都已经被初始化好了。
beforeMount:是第三个生命周期函数,表示模板已经在内存中编辑完成了,但是还没有被渲染到页面中。
mounted:第四个生命周期函数,此时内存中的模板已经挂载到了页面中,用户可以看到渲染好的页面。mounted是实例创建期间的最后一个生命周期函数,当此函数执行完毕,表示实例已经被完全创建好了。
beforeUpdate:此时界面还没有被更新。
updated:updated 事件执行的时候,页面和 data 数据已经保持同步。
beforeDestroy:销毁之前执行,当beforeDestroy函数执行时,表示vue实例已从运行阶段进入销毁阶段,vue实例身上所有的方法与数据都处于可用状态。
destroyed:当destroy函数执行时,组件中所有的方法与数据已经被完全销毁。其余三个钩子:
keep-alive 缓存组件 生命周期的钩子函数 activated deactivated
生命周期的钩子函数
activated(:当缓存组件有被显示出来时,会触发这个钩子函数
deactivated: 当缓存的组件隐藏时,会触发这个钩子函数;errorCaptured :当子孙组件出错时,会调用这个钩子函数
还有一个隐藏的钩子,经常会用到,但注意,这个钩子不是已函数形式写在script中,而是vm实例自带的一个方法,所以在vc(VueComponent)实例上也能访问:
this.$nextTick():在下次 DOM 更新循环结束之后执行延迟回调;在修改数据之后立即使用这个方法,获取更新后的 DOM。
生命周期钩子详解及注意事项
beforeCreate()
生命周期函数被执行此时不能访问data和menthods等中的东西
created()
生命周期钩子函数被执行,实例创建此时能访问data和menthods等中的东西
接下来开始编译模板:开始分析
template选项检查:
有:编译template返回render渲染函数
无:编译el选项对应标签作为template(要渲染的模板)vue工程项目不支持
虚拟DOM挂载成真实DOM之前:
beforeMount()
beforeMount :生命周期钩子函数被执行
Create vm$el and replace "el" with it:把虚拟DOM和渲染的数据一并挂到真实DOM上
挂载完毕,mounted:生命周期钩子函数被执行
mounted()
需要注意的问题,避免做项目时踩坑
在这发起后端请求,拿回数据,配合路由钩子做一些事情
详细:
el被新创建的 vm.el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当mounted被调用时vm.el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当mounted被调用时vm.el 也在文档内
该钩子在服务器端渲染期间不被调用。
注意: 如果在此钩子中向后台发送请求,无法立刻拿到数据,如有需要,可在watch中监听该数据调用this.$nextTick()获取更新后的数据
示例:
<template>
<div class="swiper-container" ref="cur">
<div class="swiper-wrapper">
<div
class="swiper-slide"
v-for="(carousel, index) in list"
:key="carousel.id">
<img :src="carousel.imgUrl" />
</div>
</div>
</div>
</template>
<script>
import Swiper from "swiper";
export default {
props: ["list"],
watch: {
list: {
immediate: true,
handler() {
if (this.list.length === 0)
return this.$nextTick(() => {
var mySwiper = new Swiper(this.$refs.cur, {
loop: true, // 循环模式选项
// observer: true,
autoplay: true,
// 如果需要分页器
pagination: {
el: ".swiper-pagination",
clickable: true,
},
// 如果需要前进后退按钮
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
// 如果需要滚动条
scrollbar: {
el: ".swiper-scrollbar",
},
});
});
},
},
},
//错误示例
mounted(){
var mySwiper = new Swiper(this.$refs.cur, {...}
}
};
</script>
<style>
</style>
错误原因:此时获取到的v-for的数据是从后台返回过来的,这需要一定的时间,此时v-for遍历不到任何数据,在数据返回之前页面已经挂载完成,即已开始执行mounted函数,而后台数据成功获取到后再页面重新渲染生成的dom元素,所以在mounted中获取不到该dom元素
beforeUpdate()
当data里数据改变, 更新DOM之前,beforeUpdate – 生命周期钩子函数被执行此时获取不到更新的真实dom
虚拟DOM重新渲染, 打补丁到真实DOM
updated – 生命周期钩子函数开始执行,当有data数据改变 – 重复这个循环
updated()
beforeDestroy()
当$destroy()被调用:比如组件DOM被移除(例v-if)
beforeDestroy:生命周期钩子函数被执行
拆卸数据监视器、子组件和事件侦听器
实例销毁后, 最后触发一个钩子函数
destroyed: 生命周期钩子函数开始执行
destroyed()
activated()
在vue对象存活的情况下,进入当前存在activated()函数的页面时,一进入页面就触发;可用于初始化页面数据等。
activated | created | |
触发顺序 | 组件创建最初始 | created => mounted >activated |
触发次数 | 只在组件刚创建时创建 | 在使用keep-alive标签中有效,每次进入都会执行钩子中的函数 |
deactivated()
路由组件失活时执行
errorCaptured ()
子孙组件出错时调用,一般不用
this.$nextTick()
当你修改了数据,vue帮你操作完dom ,把真实的dom放入页面,vue再帮你调用$nextTick