vue生命周期
Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程。
可分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
所有生命周期钩子的 this 上下文将自动绑定至实例中,因此你可以访问 data、computed 和 methods。这意味着你不应该使用箭头函数来定义一个生命周期方法
生命周期钩子函数
挂载:beforeCreate、created、beforeMount、 mounted
更新:beforeUpdate、 updated
销毁:beforeDestroy、destroyed
生命钩子 | | 说明 |
---|
beforeCreate | 在实例初始化之后, 进行数据侦听和事件/侦听器的配置之前同步调用 | 虚拟的dom 和 data 并未初始化 | created | 在实例创建完成后被立即同步调用 | data已经初始化,可以使用data中的数据、调用methods中的方法;但是dom没有完成挂载,不能操作dom | beforeMount | | 生成了虚拟dom,但是不能够操作dom | mounted | | 完成挂载,可以对dom进行操作 | beforeUpdate | | 触发条件updated一样,数据导致的页面视图变化都会触发,包括修改data中的数据,computed中的数据变化导致视图变化 | updated | 在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用 | 1》值修改了,但是没有修改视图是不会执行的,比如只是用来作为请求参数的数据被修改;或者修改前和修改后的值是一样的; 2》操作dom是不会触发updated的 | beforeDestroy | 组件销毁前 | 可以在这里清空定时器 | destroyed | 组件销毁后 | |
一旦进入组件会执行哪些生命周期
beforeCreate、created、beforeMount、 mounted
父子组件生命周期的执行顺序
一、正常引入
挂载:
1》父组件:beforeCreate 、created 、beforeMount
2》子组件:beforeCreate 、created 、beforeCreate 、 mounted
3》父组件:mounted
更新:
父组件:beforeUpdate
子组件:beforeUpdate 、updated
父组件:updated
销毁:
父组件:beforeDestroy
子组件:beforeDestroy、destroyed
父组件:destroyed
父组件引入引入了多个子组件,子组件的生命钩子函数执行先后与组件先后顺序有关
<template>
<div class="father">
<child1></child1>
<child2></child2>
</div>
</template>
import child1 from "./child.vue";
import child2 from "./child2.vue";
components: {
child1,
child2,
},
父组件:beforeCreate 、created 、beforeMount
子组件1:beforeCreate 、created 、beforeCreate
子组件2:beforeCreate 、created 、beforeCreate
子组件1:mounted
子组件2:mounted
父组件:mounted
二、子组件异步按需引入
比如我们的弹出,在不打开的时候是不需要加载的,打开弹出才加载弹出组件
异步引入返回一个promise
components: {
child: () => import("./child.vue"),
},
1》父组件:beforeCreate 、created 、beforeCreate 、 mounted、beforeUpdate
2》子组件:beforeCreate 、created 、beforeCreate 、 mounted
3》父组件:updated
异步按需引入多个子组件
<child1></child1>
<child2></child2>
components: {
child1: () => import("./child.vue"),
child2: () => import("./child2.vue"),
},
父组件:beforeCreated、created、beforeMount、mounted 、beforeUpdate
子组件1:beforeCreate 、created 、beforeCreate、 mounted
父组件:updated、beforeUpdate
子组件2:beforeCreate 、created 、beforeCreate、 mounted
父组件:updated
beforeCreate中能发请求吗?为什么不在beforeCreate中发请求呢?发请求是在created还是mounted中
beforeCreate() {
axios.post("/api/cors/resource").then((res) => {
console.log(res);
this.list = res.data;
});
},
beforeCreate中能够发请求,但是我们一般不会在这里面发请求;原因:beforeCreate中不能获取this中的数据,也不能调用methods中方法;而我们请求可能要携带参数,且参数在data中;并且请求数据我们一般会写成methods中的一个方法
上面的这个例子是可以请求到数据的,并且可以修改data中的list; 因为是异步修改的
请求我们一般是在created中或mounted,至于写在哪里还要看具体情况
一般情况下,它们的区别其实不是特别大,但是有些场景需要考虑写在哪更合适;主要考虑的是组件件生命钩子的执行先后以及它们的区别
先后顺序前面已经说了,另外一个比较大的区别就是created还没有完成dom的挂载,所以不能直接操作dom,而mounted中dom完成挂载,可以对dom进行操作
主要看你向先发哪个请求:如果父组件中created中请求的数量特别多,而子组件中created中的请求的资源是要立马显示的内容,将父组件的请求放到mounted比较好;同一个生命钩子created又都是异步,请求又比较多,肯定是先发送父组件的请求才会去发子组件的请求(就一个请求发送的先后不同;这里说的都是组件正常引入);这种情况当然也可以都写在mounted中,子组件的mounted也是先与父组件的mounted
如果请求依赖与dom,那么写在mounted更合适
如果想要更早发请求,又不依赖与dom就可以放created
如何在created中操作dom
我们不能再created中直接操作dom,会报错;因为再 created 钩子中还没有生成虚拟dom,没有完成dom的挂载
解决方法:可以将dom操作放在 $nextTick 中
created() {
this.$nextTick(() => {
document.querySelector("#test").style.color = "blue";
});
},
$nextTick :
在下次 DOM 更新循环结束之后执行延迟回调。原理与事件循环机制有关,它是一个微任务
使用场景:在修改数据之后,获取更新后的dom
修改数据后不能直接获取最新后的dom,是因为 vue 是异步执行 DOM 更新
<div id="test" style="fontSize:26px">{{ str }}</div>
data() {
return {
str: "",
};
},
mounted(){
axios.post("/api/cors/resource").then((res) => {
this.str = res.data;
// console.log(
// "获取更新后的内容",
// document.querySelector("#test").innerText
// );
this.$nextTick(() => {
console.log(
"获取更新后的内容",
document.querySelector("#test").innerText
);
});
});
}
使用了keep-alive会执行哪些生命周期
vue默认有8个生命钩子函数,但是如用了 keep-alive 的时候,activated与deactivated这了两个钩子函数也生效
钩子函数 | 调用实际 | 说明 |
---|
activated | keep-alive 缓存的组件激活时调用 | | deactivated | 被 keep-alive 缓存的组件失活时调用 | |
第一次进入页面:beforeCreate=>created=>beforeMount=>mounted=>activated
离开:deactivated
再次进入:activated
|