生命周期
- 每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。
- 生命周期如图:
beforeCreate() :创建之前
- 会在实例初始化完成、props 解析之后、
data()和computed等选项处理之前立即调用。 - 无法访问data中的状态和methods中的方法
created() :创建完成
- 当这个钩子被调用时,以下内容已经设置完成:响应式数据、计算属性、方法和侦听器。然而,此时挂载阶段还未开始,因此
$el属性仍不可用。 - 可以访问data中的状态和methods中的方法
beforeMount() :挂载前
- 当这个钩子被调用时,组件已经完成了其响应式状态的设置,但还没有创建 DOM 节点。它即将首次执行 DOM 渲染过程。
- 可以访问data中的状态和methods中的方法,但是无法访问到 dom 中的内容
mounted() :挂载完成
- 所有同步子组件都已经被挂载。这个钩子通常用于执行需要访问组件所渲染的 DOM 树相关的副作用
- 可以访问data中的状态和methods中的方法,可以访问到 dom 中的内容
beforeUpdate() :更新前
- 这个钩子可以用来在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中更改状态也是安全的。
- 能访问到更改后的元素,
- 但是无法获取最新的dom,因为此时dom还未更新(在使用v-if时,dom还未被创建)
updated() :更新完成
- 这个钩子会在组件的任意 DOM 更新后被调用,这些更新可能是由不同的状态变更导致的。
- 如果你需要在某个特定的状态更改后访问更新后的 DOM,请使用 nextTick() 作为替代。
beforeUnmount() :卸载前
- 当这个钩子被调用时,组件实例依然还保有全部的功能。
unmounted() :卸载完成
- 在一个组件实例被卸载之后调用。
- 可以在这里做清除工作
- 卸载发生在v-if为false时
父组件
<template>
<h1>App</h1>
<!-- 创建和挂载 -->
<div class="content">
<p>我是内容:</p>
{{ myname }}
</div>
<hr />
<!-- 更新 -->
<button @click="isShow = !isShow">显示 / 隐藏</button>
<p class="name" v-if="isShow">{{ myname }}</p>
<hr />
<!-- 卸载 -->
<button @click="isChild = !isChild">开启 / 关闭</button>
<Child v-if="isChild" />
</template>
<script>
import Child from "./Child.vue";
export default {
components: {
Child,
},
data() {
return {
myname: "caoxinmei",
isShow: false,
isChild: true,
};
},
beforeCreate() {
/*
创建前
无法访问data和methods中的内容
*/
console.log("beforeCreate", this.myname); // undefined
},
created() {
/*
创建后
能访问data和methods中的内容
在这里可以做初始化的操作,把复杂的data数据进行拆分
*/
console.log("created", this.myname);
},
beforeMount() {
/*
挂载前
能访问data和methods中的内容,但是无法访问到 dom 中的内容
*/
let oCon = document.querySelector(".content"); // nullo
console.log("beforeMount", this.myname, oCon);
},
mounted() {
/*
挂载完成
能访问data、methods和 dom 中的内容
可以做:
此时可以操作dom中的内容,可以做一些与dom有关的初始化操作
初始化轮播、echarts、setInterval、ajax
*/
let oCon = document.querySelector(".content");
console.log("mounted", this.myname, oCon);
},
beforeUpdate() {
/*
更新前
能访问到更改后的元素,
但是无法获取最新的dom,因为此时dom还未更新(在使用v-if时,dom还未被创建)
*/
let oName = document.querySelector(".name");
console.log("beforeUpdate", this.myname, oName);
},
// 更新完成
updated() {
/*
更新完成:
能访问到更改后的元素,并且能获取到最新的dom
*/
let oName = document.querySelector(".name");
console.log("updated", this.myname, oName);
},
};
</script>
子组件
<template>
<div>
<h2>我是子组件</h2>
</div>
</template>
<script>
export default {
// 在挂载完成后,设置一个定时器
mounted() {
this.timer = setInterval(() => {
console.log(11);
}, 200);
},
beforeUnmount() {
/*
卸载前:
*/
console.log("beforeUnmount");
},
// 可以看到在卸载完成这个组件后,定时器还是在运行
// 可以在卸载完成后,清除定时器
unmounted() {
/*
卸载完成:
这里可以做清理工作,比如:
清除定时器、取消订阅消息、清除事件监听
*/
console.log("unmounted");
clearInterval(this.timer);
},
};
</script>