2.17、vue的生命周期

所谓的生命周期是指:一个事物从出生到最终的死亡,整个经历的过程叫做生命周期。

例如人的生命周期:

(1) 出生:打疫苗

(2) 3岁了:上幼儿园

(3) 6岁了:上小学

(4) 12岁了:上初中

(5) ......

(6) 58岁了:退休

(7) ......

(8) 临终:遗嘱

(9) 死亡:火化

可以看到,在这个生命线 上有很多不同的时间节点,在不同的时间节点 上去做不同的事儿

Vue的生命周期指的是:vm对象从创建到最终销毁的整个过程。

(1) 虚拟DOM在内存中就绪时:去调用一个a函数

(2) 虚拟DOM转换成真实DOM渲染到页面时:去调用一个b函数

(3) Vue的data发生改变时:去调用一个c函数

(4) ......

(5) Vue实例被销毁时:去调用一个x函数

在生命线上的函数叫做钩子函数,这些函数是不需要程序员手动调用的,由Vue自动调用,程序员只需要按照自己的需求写上,到了那个时间点自动就会执行。

2.17.2 掌握Vue的生命周期有什么用

研究Vue的生命周期主要是研究:在不同的时刻Vue做了哪些不同的事儿。

例如:在vm被销毁之前,需要将绑定到元素上的自定义事件全部解绑,

那么这个解绑的代码就需要找一个地方写一下,写到哪里呢?你可以写到beforeDestroy()这个函数中,这个函数会被Vue自动调用,而且是在vm对象销毁前被自动调用。

像这种在不同时刻被自动调用的函数称为钩子函数。每一个钩子函数都有对应的调用时间节点。

换句话说,研究Vue的生命周期主要研究的核心是:在哪个时刻 调用了哪个钩子函数

2.17.3 Vue生命周期的4个阶段8个钩子

Vue的生命周期可以被划分为4个阶段:初始阶段、挂载阶段、更新阶段、销毁阶段。

每个阶段会调用两个钩子函数。两个钩子函数名的特点:beforeXxx()、xxxed()。

8个生命周期钩子函数分别是:

(1) 初始阶段

① beforeCreate() 创建前

② created() 创建后

(2) 挂载阶段

① beforeMount() 挂载前

② mounted() 挂载后

(3) 更新阶段

① beforeUpdate() 更新前

② updated() 更新后

(4) 销毁阶段

① beforeDestroy() 销毁前

② destroyed() 销毁后

8个钩子函数写在哪里?直接写在Vue构造函数的options对象当中。

Vue官方的生命周期图:

javascript 复制代码
  <body>
    <div id="app">
      <h1>{{msg}}</h1>
      <h3>计数器:{{counter}}</h3>
      <button @click="add">点我加1</button>

      <h3 v-text="counter"></h3>
      <button @click="destroy">点我销毁</button>
    </div>
    <script>
      const vm = new Vue({
        el: "#app",
        data: {
          msg: "Vue生命周期",
          counter: 1,
        },
        methods: {
          add() {
            console.log("add....");
            this.counter++;
          },
          destroy() {
            // 销毁vm
            this.$destroy();
          },
        },
        watch: {
          counter() {
            console.log("counter被监视一次!");
          },
        },
        /*
            1.初始阶段
                el有,template也有,最终编译template模板语句。
                el有,template没有,最终编译el模板语句。
                el没有的时候,需要手动调用 vm.$mount(el) 进行手动挂载,然后流程才能继续。
                    此时如果template有,最终编译template模板语句。
                el没有的时候,需要手动调用 vm.$mount(el) 进行手动挂载,然后流程才能继续。
                    此时如果没有template,最终编译el模板语句。

                结论:
                    流程要想继续:el必须存在。
                    el和template同时存在,优先选择template。如果没有template,才会选择el。
            */
        beforeCreate() {
          // 创建前
          // 创建前指的是:数据代理和数据监测的创建前。
          // 此时还无法访问data当中的数据。包括methods也是无法访问的。
          console.log("beforeCreate", this.counter);
          // 调用methods报错了,不存在。
          //this.add()
        },
        created() {
          // 创建后
          // 创建后表示数据代理和数据监测创建完毕,可以访问data中的数据了。
          console.log("created", this.counter);
          // 可以访问methods了。
          //this.add()
        },
        // 2.挂载阶段
        beforeMount() {
          // 挂载前
          console.log("beforeMount");
          //   debugger  //断点
        },
        mounted() {
          // 挂载后
          console.log("mounted");
          // 创建真实dom元素
          console.log(this.$el);
          console.log(this.$el instanceof HTMLElement);
        },
        // 3.更新阶段
        beforeUpdate() {
          // 更新前
          console.log("beforeUpdate");
        },
        updated() {
          // 更新后
          console.log("updated");
        },
        // 4.销毁阶段
        beforeDestroy() {
          // 销毁前,解绑vue
          console.log("beforeDestroy");
          console.log(this);
          this.counter = 1000;
        },
        destroyed() {
          // 销毁后,vm依然存在,不过是vm身上的事件,监听解绑
          console.log("destroyed");
          console.log(this);
        },
      });
    </script>
  </body>

2.17.4 初始阶段做了什么事儿

做了这么几件事:

(1) 创建Vue实例vm(此时Vue实例已经完成了创建,这是生命的起点)

(2) 初始化事件对象和生命周期(接产大夫正在给他洗澡)

(3) 调用beforeCreate()钩子函数(此时还无法通过vm去访问data对象的属性)

(4) 初始化数据代理和数据监测

(5) 调用created()钩子函数(此时数据代理和数据监测创建完毕,已经可以通过vm访问data对象的属性)

(6) 编译模板语句生成虚拟DOM(此时虚拟DOM已经生成,但页面上还没有渲染)

该阶段适合做什么?

beforeCreate:可以在此时加一些loading效果,自定义一些属性放到this身上,好比全局事件总线

created:结束loading效果。也可以在此时发送一些网络请求,获取数据。也可以在这里添加定时器。

2.17.5 挂载阶段做了什么事儿

做了这么几件事:

(1) 调用beforeMount()钩子函数(此时页面还未渲染,真实DOM还未生成,此时操作数据,不会最终显示在页面中)

(2) 给vm追加el属性,用它来代替"el",el代表了真实的DOM元素(此时真实DOM生成,页面渲染完成)

(3) 调用mounted()钩子函数

该阶段适合做什么?

mounted:可以操作页面的DOM元素了。也有人喜欢在这个阶段请求数据

面试题:请求数据是在哪个钩子里,原因是什么?

2.17.6 更新阶段做了什么事儿

(1) data发生变化(这是该阶段开始的标志)

(2) 调用beforeUpdate()钩子函数(此时只是内存中的数据发生变化,页面还未更新)

(3) 虚拟DOM重新渲染和修补

(4) 调用updated()钩子函数(此时页面已更新)

该阶段适合做什么?

beforeUpdate:适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

updated:页面更新后,如果想对数据做统一处理,可以在这里完成。

2.17.7 销毁阶段做了什么事儿

做了这么几件事:

(1) vm.$destroy()方法被调用(这是该阶段开始的标志)

(2) 调用beforeDestroy()钩子函数(此时Vue实例还在。虽然vm上的监视器、vm上的子组件、vm上的自定义事件监听器还在,但是它们都已经不能用了。此时修改data也不会重新渲染页面了)

(3) 卸载子组件和监视器、解绑自定义事件监听器

(4) 调用destroyed()钩子函数(虽然destroyed翻译为已销毁,但此时Vue实例还在,空间并没有释放,只不过马上要释放了,这里的已销毁指的是vm对象上所有的东西都已经解绑完成了)

该阶段适合做什么?

beforeDestroy:适合做销毁前的准备工作,和人临终前写遗嘱类似。例如:可以在这里清除定时器,解绑自定义事件,解除监听等

若有收获,就点个赞吧

相关推荐
呆呆在发呆.4 分钟前
计组实验-Bomb Lab -2
java·服务器·前端
笨笨狗吞噬者5 分钟前
为了解决路径问题,我写了一个eslint plugin
前端·javascript·eslint
威威猫的栗子8 分钟前
用 Python Turtle 绘制经典汤姆猫:重温卡通角色的经典魅力
开发语言·python
老马啸西风10 分钟前
开源分布式系统追踪-01-Zipkin-01-入门介绍
java
工一木子16 分钟前
【Leecode】Leecode刷题之路第82天之删除排序链表中的重复元素II
java·数据结构·算法·leetcode·链表
星辰@Sea18 分钟前
Python 实现对人的行为预测
开发语言·python
亽仒凣凣36 分钟前
Tomcat官网下载安装
java·tomcat
Amor风信子37 分钟前
华为OD机试真题---机房布局
java·开发语言·数据结构·算法·华为od
星霜旅人43 分钟前
Python的基础知识
开发语言·python·numpy
唐棣棣1 小时前
期末速成C++【类和对象】
开发语言·c++