vue的生命周期

Posted JingG459

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue的生命周期相关的知识,希望对你有一定的参考价值。

目录

一. 什么是生命周期 

 二. 钩子函数

1.初始化阶段

在 beforeCreated 阶段

在 created 阶段

2. 挂载阶段

在 beforeMount 阶段

在 mounted 阶段

3. 更新阶段

更新前后:

5. 销毁阶段

 销毁前后:

 三. 钩子函数(不常用)

1. 组件激活时

未激活时(activated/deactivated):

2. 捕获错误时

当捕获一个来自后代组件的错误时被调用(errorCaptured):


一. 什么是生命周期 

        一组件从 创建销毁 的整个过程就是生命周期

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

 二. 钩子函数

作用: 特定的时间点,执行特定的操作

场景: 组件创建完毕后,可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数据

分类: 4大阶段8个方法(总共有十一个,常用的有八个,另外三个将会在结尾简单介绍)

1.初始化阶段

在 beforeCreated 阶段

        vue实例的挂载元素 $el 和数据对象 data 都为 undefined,还未初始化

在 created 阶段

        vue实例的数据对象 data 有了,但 $el 还没有 

        下面是在初始化阶段的两个钩子的作用执行时机

  1. new Vue() – Vue实例化(组件也是一个小的Vue实例)
  2. Init Events & Lifecycle – 初始化事件和生命周期函数
  3. beforeCreate – 生命周期钩子函数被执行
  4. Init injections&reactivity – Vue内部添加data和methods等
  5. created – 生命周期钩子函数被执行, 实例创建
  6. 接下来是编译模板阶段 –开始分析
  7. Has el option? – 是否有el选项 – 检查要挂到哪里      

    没有. 调用$mount()方  ;有, 继续检查template选项

<script>
export default {
    data(){
        return {
            msg: "hello, Vue"
        }
    },
    // 一. 初始化
    // new Vue()以后, vue内部给实例对象添加了一些属性和方法, data和methods初始化"之前"
    beforeCreate(){
        console.log("beforeCreate -- 执行");
        console.log(this.msg); // undefined
    },
    // data和methods初始化以后
    // 场景: 网络请求, 注册全局事件
    created(){
        console.log("created -- 执行");
        console.log(this.msg); // hello, Vue

        this.timer = setInterval(() => {
            console.log("哈哈哈");
        }, 1000)
    }
}
</script>

2. 挂载阶段

在 beforeMount 阶段

        vue实例的 $el 和 data 都初始化完成,但还没有挂载虚拟的 DOM 节点,data.message还没替换

在 mounted 阶段

        vue实例挂载完成,data.message 成功渲染

        下面是在初始化阶段的两个钩子的作用执行时机

  1. template选项检查
  2. 有 - 编译template返回render渲染函数
  3. 无 – 编译el选项对应标签作为template(要渲染的模板)
  4. 虚拟DOM挂载成真实DOM之前
  5. beforeMount – 生命周期钩子函数被执行
  6. Create … – 把虚拟DOM和渲染的数据一并挂到真实DOM上
  7. 真实DOM挂载完毕
  8. mounted – 生命周期钩子函数被执行

<template>
  <div>
      <p>学习生命周期 - 看控制台打印</p>
      <p id="myP">{{ msg }}</p>
  </div>
</template>

<script>
export default {
    // ...省略其他代码
    
    // 二. 挂载
    // 真实DOM挂载之前
    // 场景: 预处理data, 不会触发updated钩子函数
    beforeMount(){
        console.log("beforeMount -- 执行");
        console.log(document.getElementById("myP")); // null

        this.msg = "重新值"
    },
    // 真实DOM挂载以后
    // 场景: 挂载后真实DOM
    mounted(){
        console.log("mounted -- 执行");
        console.log(document.getElementById("myP")); // p
    }
}
</script>

 

3. 更新阶段

更新前后:

        当 data 变化时,会触发 beforeUpdate 和 updated 方法

  1. 当data里数据改变, 更新DOM之前
  2. beforeUpdate – 生命周期钩子函数被执行
  3. Virtual DOM…… – 虚拟DOM重新渲染, 打补丁到真实DOM
  4. updated – 生命周期钩子函数被执行
  5. 当有data数据改变 – 重复这个循环

        准备ul+li循环, 按钮添加元素, 触发data改变->导致更新周期开始  

<template>
  <div>
      <p>学习生命周期 - 看控制台打印</p>
      <p id="myP">{{ msg }}</p>
      <ul id="myUL">
          <li v-for="(val, index) in arr" :key="index">
              {{ val }}
          </li>
      </ul>
      <button @click="arr.push(1000)">点击末尾加值</button>
  </div>
</template>

<script>
export default {
    data(){
        return {
            msg: "hello, Vue",
            arr: [5, 8, 2, 1]
        }
    },
    // ...省略其他代码

    // 三. 更新
    // 前提: data数据改变才执行
    // 更新之前
    beforeUpdate(){
        console.log("beforeUpdate -- 执行");
        console.log(document.querySelectorAll("#myUL>li")[4]); // undefined
    },
    // 更新之后
    // 场景: 获取更新后的真实DOM
    updated(){
        console.log("updated -- 执行");
        console.log(document.querySelectorAll("#myUL>li")[4]); // li
    }
}
</script>

5. 销毁阶段

 销毁前后:

        在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时的 vue 实例已经解除了事件监听以及和 DOM 的绑定,但是 DOM 结构依然存在

  1. 当$destroy()被调用 – 比如组件DOM被移除(例v-if)
  2. beforeDestroy – 生命周期钩子函数被执行
  3. 拆卸数据监视器、子组件和事件侦听器
  4. 实例销毁后, 最后触发一个钩子函数
  5. destroyed – 生命周期钩子函数被执行

 组件即将要被删除:

<script>
export default {
    // ...省略其他代码
    
    // 四. 销毁
    // 前提: v-if="false" 销毁Vue实例
    // 场景: 移除全局事件, 移除当前组件, 计时器, 定时器, eventBus移除事件$off方法
    beforeDestroy(){
        // console.log('beforeDestroy -- 执行');
        clearInterval(this.timer)
    },
    destroyed(){
        // console.log("destroyed -- 执行");
    }
}
</script>

 在 App.vue 中点击按钮让组件从DOM上移除 -> 导致组件进入销毁阶段

<Life v-if="show"></Life>
<button @click="show = false">销毁组件</button>

<script>
    data(){
        return {
            show: true
        }
    },
</script>

 三. 钩子函数(不常用)

         这两个钩子现在已经很少有人使用了,了解一下就好

1. 组件激活时

未激活时(activated/deactivated):

        这两个钩子函数呢一般配合<keep-alive><keep-alive/>来使用。

        通常一个组件是很大的,如果我们总是一直创建、销毁、创建、销毁。。。这样很不合理,而且很浪费性能,这时候我们就可以用<keep-alive><keep-alive/>配合着两个钩子函数来控制组件的激活和不激活

2. 捕获错误时

当捕获一个来自后代组件的错误时被调用(errorCaptured):

        当子孙组件报错的时候,父组件会触发这个钩子函数,并且会返回三个参数, 第一个参数是 错误对象 ,第二个参数是 报错的子孙组件 ,第三个参数是 报错的子孙组件的具体哪个地方报错。

以上是关于vue的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

在不存在的片段上调用片段生命周期和 onCreate 的问题

Android片段生命周期:onResume调用了两次

导航上的片段生命周期重叠

Android 片段生命周期

关于片段生命周期,何时调用片段的 onActivityResult?

理解片段事务期间片段的生命周期方法调用