生命周期:一个组件从 创建 到 销毁 的整个过程就是生命周期
生命周期函数(钩子函数)
vue 框架内置函数,随着组件的生命周期,自动 按次序 执行
作用:特定的时间点,执行某些特定的操作
场景: 组件创建完毕后,可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数据
四个阶段:
- 初始化 => 创建组件 => beforeCreate created
- 挂载 => 渲染显示组件 => beforeMount mouted
- 更新 => 修改了变量 => 触发视图刷新 => beforeUpdate updated
- 销毁 => 切换页面 => 会把组件对象从内存删除 => beforeDestory destoryed
在一个组件中的生命周期都由这四个阶段八个钩子组成的
那如果是父组件套用子组件呢?这个执行规则又是怎么样的?
首先我们需要准备好素材如下
子组件
<template>
<div>
<ul id="myUl">
<li v-for="(item, ind) in arr" :key="ind">{{ item }}</li>
</ul>
<button @click="arr.push(Math.random() * 10)">增加一个元素</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "我是变量",
arr: [1, 2, 3, 4],
isShow: true,
};
},
beforeCreate() {
// 1. 创建前
console.log("子组件的beforeCreate --- 实例初始化前");
console.log(this.msg); // undefined
},
created() {
// 2. 创建后=> 发送ajax请求
console.log("子组件的created --- 实例初始化后");
console.log(this.msg); // "我是变量"
},
beforeMount() {
// 3. 挂载前
console.log("子组件的beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前");
console.log(document.getElementById("myUl")); // null
// console.log(document.getElementById("myUl").children[1].innerHTML) // 报错
},
mounted() {
// 4. 挂载后=> 操作dom
// setInterval(function () {
// console.log(Date.now());
// }, 1000);
console.log("子组件的mounted --- vue的虚拟DOM, 挂载到真实的网页上 ");
// console.log(document.getElementById("myUl").children[1].innerHTML)
console.log(document.querySelector("#myUl").children[1].innerText);
},
beforeUpdate() {
// 5. 更新前
console.log("子组件的beforeUpdate --- 数据更新, 页面更新前");
// 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
// console.log(document.getElementById("myUl").children[4].innerHTML) // 报错
},
updated() {
// 6. 更新后
console.log("子组件的updated --- 数据更新, 页面更新后");
console.log(document.getElementById("myUl").children[4].innerHTML);
},
beforeDestroy() {
// 7. 销毁前
// (清除定时器 / 解绑js定义的事件)
console.log("子组件的beforeDestroy --- 实例销毁之前调用");
},
destroyed() {
// 8. 销毁后
// (清除定时器 / 解绑js定义的事件)
console.log("子组件的destroyed --- 销毁完成");
},
};
</script>
<style>
</style>
父组件
<template>
<div>
<Life v-if="isShow" />
<hr />
<button @click="isShow = !isShow">销毁Life组件</button>
</div>
</template>
<script>
import Life from "./Life.vue";
export default {
data() {
return {
isShow: true,
};
},
beforeCreate() {
// 1. 创建前
console.log("父组件的beforeCreate --- 实例初始化前");
console.log(this.msg); // undefined
},
created() {
// 2. 创建后=> 发送ajax请求
console.log("父组件的created --- 实例初始化后");
console.log(this.msg); // "我是变量"
},
beforeMount() {
// 3. 挂载前
console.log("父组件的beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前");
console.log(document.getElementById("myUl")); // null
// console.log(document.getElementById("myUl").children[1].innerHTML) // 报错
},
mounted() {
// 4. 挂载后=> 操作dom
// setInterval(function () {
// console.log(Date.now());
// }, 1000);
console.log("父组件的mounted --- vue的虚拟DOM, 挂载到真实的网页上 ");
// console.log(document.getElementById("myUl").children[1].innerHTML)
console.log(document.querySelector("#myUl").children[1].innerText);
},
beforeUpdate() {
// 5. 更新前
console.log("父组件的beforeUpdate --- 数据更新, 页面更新前");
// 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
// console.log(document.getElementById("myUl").children[4].innerHTML) // 报错
},
updated() {
// 6. 更新后
console.log("父组件的updated --- 数据更新, 页面更新后");
console.log(document.getElementById("myUl").children[4].innerHTML);
},
beforeDestroy() {
// 7. 销毁前
// (清除定时器 / 解绑js定义的事件)
console.log("父组件的beforeDestroy --- 实例销毁之前调用");
},
destroyed() {
// 8. 销毁后
// (清除定时器 / 解绑js定义的事件)
console.log("父组件的destroyed --- 销毁完成");
},
components: {
Life,
},
};
</script>
在控制台输出的结果如下
得出的结论是父组件会会先触发-初始化前->初始化后->挂载前,然后触发了子组件的初始化之前->初始化之后->挂载前->挂载后,再触发父组件的挂载结束