vue2生命周期

166 阅读2分钟

基础

介绍:
	vue生命周期就是`vue实例从创建到销毁的整个过程`我们称之为vue的生命周期,通过vue的生命周期我们可以在不同阶段进行不同的逻辑操作.

vue生命周期钩子函数:
	01.beforeCreate    实例了Vue但还没进行数据的初始化与响应式处理
    02.created         数据已被初始化和响应式处理,在这里可以访问到数据,也可以修改数据
    03.beforeMount     render函数在这里被调用,生成虚拟DOM,但是还没被转成真实DOM并替换到el
    04.mounted         在这里,真实DOM挂载完毕
    05.beforeUpdate    数据更新后,新的虚拟DOM生成,但还没有跟旧虚拟DOM对比打补丁
    06.update          新旧虚拟DOM对比打补丁后,进行真实DOM的更新
    07.activated       被keep-alive缓存的组件被激活时调用
    08.deactivated     被keep-alive缓存的组件停用时调用
    09.beforeDestory   实例销毁之前调用,在这一步,依然可以访问数据
    10.destoryed       实例销毁后调用,该钩子被调用后,对应Vue实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁
    11.errorCaptured   当捕获一个来自子孙组件的错误时被调用,此钩子会收到三个参数:错误对象、发生错误的组件实例、一个包含错误来源信息的字符串.此钩子可以返回false以阻止该错误继续向上传播
	上述钩子中,服务端调用的有 beforeCreate、created、errorCaptured进行了调用
	
vue生命周期常用的钩子函数有8个:
	beforeCreate(创建前)、created(创建后)、beforeMount(挂载前)、mounted(挂载后)、beforeUpdate(更新前)、updated(更新后)、beforeDestory(销毁前)、destoryed(销毁后)    

钩子函数何时加载
	`页面一开始加载的时候就会触发创建前后和挂载前后的钩子函数`
    更新的钩子函数:  需要当我们改变data的时候才能出发 <b>销毁的钩子函数:</b>   必须得当组件进行切换的时候就会进行销毁
    在项目开发过程中: 经常使用的钩子函数有created还有mounted
    获取不到dom元素,我们经常在`mounted里面获取dom元素`(有时候也存在获取不到dom元素的情况,这个时候一般用$nextTick方法来解决)

具体生命周期

每个生命周期钩子函数具体发生的事情:
     01.beforeCreate(创建前):在此生命周期函数执行的时候,data和methods中的数据都还没有初始化
     02.created(创建后):在此生命周期中,data和methods都已经被初始化好了,如果要调用methods中的方法,或者操作data中的数据,最早只能在created中操作.
     03.beforeMount(载入前):在此生命周期函数执行的时候,模板已经在内存中编译好了,但是尚未挂载到页面中去,此时页面还是旧的.
     04.mounted(载入后):此时页面和内存中都是最新的数据,这个钩子函数是最早可以操作dom节点的方法
     05.beforeUpdate(更新前):此时页面中显示的数据还是旧的,但是data中的数据是最新的,且页面并未和最新的数据同步
     06.Updated(更新后):此时页面显示数据和最新的data数据同步
     07.beforeDestory(销毁前):当执行该生命周期函数的时候,实例身上所有的data,所有的methods以及过滤器...等都处于可用状态,并没有真正执行销毁
     08.destoryed(销毁后):此时组件已经被完全销毁,示例中的所有的数据、方法、属性、过滤器...等都已经不可用了
   9-10 配合使用 配合keep-alive缓存组件使用
     09.activated(组件激活时):和上面的beforeDestory和destoryed用法差不多,但是如果我们需要一个实例,在销毁后再次出现的话,用beforeDestory和destoryed太浪费性能了.实例被激活时使用,用于重复激活一个实例的时候
     10.deactivated(组件未激活时):实例没有被激活时
     11.errorCaptured(错误调用):当捕获一个来自后代组件的错误时被调用
结合实践:
	 1.beforeCreate:通常用于插件开发中执行一些初始化任务
     2.created:组件初始化完毕,可以访问各种数据,获取接口数据等
     3.mounted:dom已创建,可用于获取访问数据和dom元素;访问子组件等等
     4.beforeUpdate:此时`view`层还未更新,可用于获取更新前各种状态
     5.updated:完成`view`层的更新,更新后,所有状态已是最新
     6.beforeDestory:实例被销毁前调用,可用于一些定时器或订阅的取消
     7.destoryed:销毁一个实例.可清理它与其他实例的连接,解绑它的全部指令及事件监听器

执行顺序

父组件和子组件生命周期钩子函数执行顺序:
加载渲染过程:
	父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
更新过程:
	父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 Updated
销毁过程:
	父 beforeDestory -> 子 beforeDestory -> 子 destoryed -> 父 destroyed
	
父组件可以监听到子组件的生命周期,使用$emit或者使用@hook:
$emit,子传父,父组件监听子组件绑定的事件接收传值
@hook 方法不仅仅是可以监听 mounted,也可以监听其它的生命周期事件。(@hook:mounted="onMounted")


生命周期展示

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vue2生命周期展示</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <style></style>
</head>

<body>
    <!--
      activated  和keep-alive 一起使用,组件激活加载触发
      deactivated 和keep-alive 一起使用,组件卸载触发

      1.你是在哪个生命周期 请求数据?
        在created和mounted都是可以的,我一般在mounted里处理。
      2. created和mounted有啥区别、
         created是在模板渲染成HTML前调用的,此时data已经准备完毕,el仍是undefined,因为没有渲染成HTML,
         mounted是在模板渲染成HTML之后调用的,此时data,el都已准备好,可以操作html的dom节点,
      3. 分别在这些生命周期钩子函数做啥?
          自己总结
          12个生命周期钩子函数

          常见的
          1. beforeCreate
          2. created
          3. beforeMount
          4. mounted
          5. beforeUpdate
          6. updated
          7. beforeDestroy
          8. destroyed


          <keep-alive>这里使用
          9. activated
         10.  deactivated


        11. errorCaptured 报错
        12. serverPrefetch  ssr服务端渲染的钩子

     -->
    <div id="app">{{ msg }}</div>

    <script>
        let app = new Vue({
            el: "#app",
            data: {
                msg: "vue的生命周期钩子函数"
            },
            methods: {
                fn(n) {
                    console.log("我是fn", n);
                }
            },
            components: {},
            beforeCreate() {
                console.group("-----beforeCreate创建前-------");
                console.log("el:", this.$el); // undefined
                console.log("data:", this.$data); // undefined
                console.log("msg:", this.msg); // undefined
                console.log("fn:", this.fn); // undefined
                console.groupEnd();
            },
            created() {
                console.group("-----created创建后-------");
                console.log("el:", this.$el); // undefined
                console.log("data:", this.$data); // 数据此时已经可以拿到   数据已被初始化
                console.log("msg:", this.msg); // 数据此时已经可以拿到    数据已被初始化
                console.log("fn:", this.fn); // 事件已经存在
                console.groupEnd();
            },
            beforeMount() {
                console.group("-----beforeMount挂载前-------");
                console.log("el:", this.$el);      // dom初始化完成
                console.log("data:", this.$data); // 数据此时已经可以拿到
                console.log("msg:", this.msg); // 数据此时已经可以拿到
                this.fn("beforeMount挂载前");
                console.groupEnd();
            },
            mounted() {
                console.group("-----mounted挂载后-------");
                console.log("el:", this.$el);      // dom初始化完成
                console.log("data:", this.$data); // 数据此时已经可以拿到
                console.log("msg:", this.msg); // 数据此时已经可以拿到
                this.fn("mounted挂载后");
                console.groupEnd();
            },
            beforeUpdate() {
                console.group("-----beforeUpdate更新前-------");
                console.log("el:", this.$el); // undefined     // dom初始化完成
                console.log("data:", this.$data); // 数据此时已经可以拿到
                console.log("msg:", this.msg); // 数据此时已经可以拿到
                this.fn("beforeUpdate更新前");
                console.groupEnd();
            },
            updated() {
                console.group("-----updated更新后-------");
                console.log("el:", this.$el); // undefined     // dom初始化完成
                console.log("data:", this.$data); // 数据此时已经可以拿到
                console.log("msg:", this.msg); // 数据此时已经可以拿到
                this.fn("updated更新后");
                console.groupEnd();
            },
            beforeDestroy() {
                console.group("-----beforeDestory销毁前-------");
                console.log("el:", this.$el); // undefined     // dom初始化完成
                console.log("data:", this.$data); // 数据此时已经可以拿到
                console.log("msg:", this.msg); // 数据此时已经可以拿到
                this.fn("beforeDestory销毁前");
                console.groupEnd();
            },
            destroyed() {
                console.group("-----destoryed销毁后-------");
                console.log("el:", this.$el); // undefined     // dom初始化完成
                console.log("data:", this.$data); // 数据此时已经可以拿到
                console.log("msg:", this.msg); // 数据此时已经可以拿到
                this.fn("destoryed销毁后");
                console.groupEnd();
            }
        });

        setTimeout(() => {
            app.msg = "123456";
        }, 5000);
    </script>
</body>

</html>