持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
什么是组件生命周期
一个组件从 创建 到 销毁 的整个过程就是生命周期,从vue官网我们可以看到一共是11个钩子,但我们经常谈论的是四个阶段,八个钩子
生命周期函数(钩子函数)
vue 框架内置函数,随着组件的生命周期,自动 按次序 执行
作用:特定的时间点,执行某些特定的操作
场景: 组件创建完毕后,可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数据
四个阶段:
- 初始化 => 创建组件
graph TD
beforeCreate --> created
- 挂载 => 渲染显示组件
graph TD
beforeMount --> mouted
- 更新 => 修改了变量 => 触发视图刷新
graph TD
beforeUpdate --> updated
- 销毁 => 切换页面 => 会把组件对象从内存删除
graph TD
beforeDestory --> destoryed
基本结构
<template>
<div>
<ul>
<li v-for="(item, index) in arr" :key="index">{{ item.name }}</li>
</ul>
<p>{{text}}</p>
</div>
</template>
<script>
export default {
data () {
return {
text: "哈哈哈",
arr: [{name:"haha",age:14,gender:"女"},
{name:"yaya",age:20,gender:"男"},
{name:"vava",age:4,gender:"女"},
{name:"hehe",age:19,gender:"男"},]
}
},
</script>
初始化
1.new Vue()
表示创建了一个Vue实例对象,
const App=new Vue()
2.Init Events&Lifecycle
在这里Vue实例对象被初始化,只包含一些默认的生命周期和默认的方法
生命周期1: beforeCreate()在beforeCreate生命周期执行的时候,data和methods中的数据都还没有被初始化 在这里想使用data和methods中的数据是获取不到的
beforeCreate () {
// 1. beforeCreate --- 实例初始化前
console.log(this.text) // undefined
},
3.Init injections&reactivity
在这里,data和methods被初始化
生命周期2:created()created生命周期函数被执行的时候,就可以使用和操作data和methods了
created经常用于页面刚加载发送ajax请求数据
created () {
// 2. created --- 实例初始化后=> 发送ajax请求
console.log(this.text) // "哈哈哈"
}
挂载
如果Vue实例中没有配置el,则生命周期不会继续向下运行,直到挂载函数被执行,才会执行后续的生命周期
4-6 检测配置
这里表示Vue开始编译模版
最终在内存中生成一个编译好的模板字符串,然后把这个模版字符串,渲染为内存中的DOM,此时,渲染好的模板,只是在内存中,还没有真正挂载到页面中去
生命周期3:beforeMount()beforeMount被执行的时候,模版已经在内存中被渲染好了,只是还没有挂载到浏览器界面中去
beforeMount () {
// 3. 挂载前:beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前
console.log(document.querySelector("ul")) // null
console.log(document.querySelector("ul").children[1].innerHTML) // 报错
},
7.Create vm.$el and replace"el" with it
这一步,会将内存中渲染好的模板,真实的替换到浏览器中去
生命周期4:mounted()mounted被执行的时候, vue的虚拟DOM, 挂载到真实的网页上
mounted () {
// 4. 挂载后=>mounted --- vue的虚拟DOM, 挂载到真实的网页上
console.log(document.querySelector('ul').children[1].innerText)
},
更新
运行阶段的生命周期函数只有两个,beforeUpdate,updated
这两个事件,会根据data数据的改变执行0次或者多次
当数据更新时,beforeUpdate开始
生命周期5: beforeUpdate ()当执行beforeUpdate的时候,页面中显示的数据还是旧的,此时data数据是最新的,页面还没有和data保持同步
beforeUpdate () {
// 5. 更新前 => beforeUpdate --- 数据更新, 页面更新前
// 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
// console.log(document.getElementById("ul").children[4].innerHTML) // 报错
},
8.Virtual DOMre-renderand patch
这一步执行的是:先根据data中的最新数据,在内存中重新渲染出一份最新的内存DOM树,
当最新的内存DOM树更新之后,会重新渲染到真实的页面中去,这时候,就完成了数据从data(model)层 ----> view(视图层)的更新
生命周期6: updated ()执行updated的时候,页面的数据已经是最新的,和data保持同步了
updated () {
// 6. 更新后 => updated --- 数据更新, 页面更新后
//点击新增数组元素,页面更新, 可以获取到新增的li标签
console.log(document.getElementById("myUl").children[4].innerHTML)
},
销毁
当vue的destroy函数被调用时,,开始进入到销毁阶段
(通过v-if的切换,可以触发子组件的destory)
生命周期7: beforeDestroy ()当执行beforeDestroy钩子函数的时候,Vue实例就已经从运行阶段,进入到了销毁阶段;实例身上所有的data和所有的methods ,以及过滤器、指令.......都处于可用状态,此时,还没有真正执行销毁的过程
9.Teardown watchers, child components and event listeners
清除监视器、子组件和事件侦听器
生命周期8: destroyed ()当执行到destroyed函数的时候,组件已经被完全销毁了,此时,组件中所有的数据、方法、指令、过滤器....都已经不可用了
点击按钮,通过isShow的true或者false来创建或销毁组件,从true到false就会执行beforeDestroy 和destroyed钩子
<template>
<div>
<MyCom v-if="isShow"/>
<hr>
<button @click="isShow = !isShow">销毁组件</button>
</div>
</template>
<script>
import MyCom from './MyCom'
export default {
data(){
return {
isShow: true
}
},
components: {
MyCom
}
};
</script>
这就是vue组件的四个阶段八个钩子