什么是生命周期
简单来说就是一个人从出生到死亡的过程
在vue中就是从Vue实例, 创建到销毁的过程
也就是从开始创建、初始化数据、编译模板、挂在 dom -> 渲染、更新 -> 渲染、准备销毁、销毁在等一系列过程
生命周期的作用
特定时间点 执行特定的操作
生命周期的场景
组件创建完毕后 可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数据
钩子函数
共分为四大阶段八大方法
| 阶段 | 方法名 | 方法名 |
|---|---|---|
| 初始化阶段 | beforeCreate | created |
| 挂载阶段 | beforeMount | mounted |
| 更新阶段 | beforeUpdate | updated |
| 销毁阶段 | beforeDestroy | destroyed |
初始化阶段
Init Events & Lifecycle – 初始化事件和生命周期函数
beforeCreate – 生命周期钩子函数被执行
Init injections&reactivity – Vue内部添加data和methods等
created – 生命周期钩子函数被执行, 实例创建
接下来是编译模板阶段 –开始分析
Has el option? – 是否有el选项 – 检查要挂到哪里
如果有--就继续检查template选项
如果没有 -- - 没有. 调用$mount()方法
注意点 :
created函数触发能获取data但是不能不能获取真实DOM
在beforeCreate执行的时候,data和method 还没有初始化,只有一些vue默认的方法
在created 执行的时候,data和method已经初始化完成可以操作了
具体代码
<template>
<div>
<h2>初始化</h2>
<p>{{ msg }}</p>
</div>
</template>
<script>
export default {
data() {
return {
msg: 'hello'
}
},
methods: {
show() {
console.log('打印hello')
}
},
beforeCreate() {
// 想要在这个函数里面 获取到 data 里面定义的变量以及 methods 里面定义的函数
console.log('beforeCreate 钩子函数触发了')
// console.log(this.msg)
// this.show()
},
created() {
// 获取 data 里面定义的变量 和调用 methods 里面的函数
// 使用的最多 可以发送 ajax 请求
console.log('create 钩子函数触发了')
console.log(this.msg)
this.show()
}
}
</script>
<style>
</style>
控制台效果
挂载阶段
template选项检查
如果有 -- 编译template返回render渲染函数
如果没有 -– 编译el选项对应标签作为template(要渲染的模板)
虚拟DOM挂载成真实DOM之前
beforeMount – 生命周期钩子函数被执行
Create … – 把虚拟DOM和渲染的数据一并挂到真实DOM上
真实DOM挂载完毕
mounted – 生命周期钩子函数被执行
注意点 :
mounted可以获取真实的DOM
在beforeMount 执行的时候,模板已经在内存中渲染好了、但还没有真正渲染到页面中去
在mounted 执行的时候,将内存中渲染好的模板, 真实的替换到浏览器中
执行完mounted, Vue实例的初始化阶段就已经结束, 此时已经脱离创建阶段, 进入运行阶段
运行阶段只有两个周期函数, 会根据data数据的改变执行0或者多次
具体代码 :
<template>
<div>
<h2>挂载阶段</h2>
<p id="p1"> {{ msg }} </p>
</div>
</template>
<script>
export default {
data() {
return {
msg: 'hello'
}
},
beforeMount() {
// 获取不到真实DOM
console.log('挂载前')
},
mounted() {
console.log('挂载后')
// 可以获取 真实DOM
console.log(document.querySelector('#p1'))
console.log(document.querySelector('#p1').innerHTML)
console.log(this.msg)
}
}
</script>
<style>
</style>
控制台效果 :
更新阶段
当data里数据改变, 更新DOM之前
beforeUpdate – 生命周期钩子函数被执行
Virtual DOM…… – 虚拟DOM重新渲染, 打补丁到真实DOM
updated – 生命周期钩子函数被执行
当有data数据改变 – 重复这个循环
注意点 :
在beforeUpdate执行的时候,页面显示的数据还是旧的, 但是data数据已经是最新的, 页面还没有和data保持同步。
在updated执行的时候,已经把更新后的数据渲染到视图中去了, 页面的数据已经是最新的, 和data保持同步了。
具体代码
<template>
<div>
<h2>更新阶段</h2>
<p id="p2"> {{ msg }} </p>
<button @click="msg = '小哥哥'">change</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: 'hello'
}
},
beforeUpdate() {
// 只有 data 里面的数据发生了改变 才会触发
// beforeUpdate 获取不到 改变后的数据 因为 虚拟 DOM 还没有重新渲染 并且将
// 真实的DOM 打补丁
console.log('beforeUpdate')
console.log(document.querySelector('#p2').innerHTML)
},
updated() {
// updated 可以获取到 修改后的数据
console.log('update')
console.log(document.querySelector('#p2').innerHTML)
}
}
</script>
<style>
</style>
控制台效果
销毁阶段
当$destroy()被调用 – 比如组件DOM被移除(例v-if)
beforeDestroy – 生命周期钩子函数被执行
拆卸数据监视器、子组件和事件侦听器
实例销毁后, 最后触发一个钩子函数
destroyed – 生命周期钩子函数被执行
注意点 :
在beforeDestroy 执行的时候,实例进入准备销毁的阶段、此时data 、methods 、指令等还是可用状态
在destroyed执行的时候,实例已经完成销毁、此时data 、methods 、指令等都不可用
具体代码
<template>
<div>
<h2>销毁阶段</h2>
<button @click="set">开始定时器</button>
</div>
</template>
<script>
export default {
data() {
return {
timerId: null
}
},
beforeDestroy() {
console.log('销毁前')
},
destroyed() {
clearInterval(this.timerId)
console.log('销毁后')
},
methods: {
set() {
this.timerId = setInterval(()=>{
document.querySelector('#p2').innerHTML += 1
// let inner = document.querySelector('#p2').innerHTML
// document.querySelector('#p2').innerHTML = inner + 1
},1000)
}
}
}
</script>
<style>
</style>
控制台效果 :
父子组件的生命周期
1. 加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
2. 子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
3. 父组件更新过程
父beforeUpdate->父updated
4. 销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
钩子函数的全图