vue组件的生命周期

237 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

什么是组件生命周期

一个组件从 创建 到 销毁 的整个过程就是生命周期,从vue官网我们可以看到一共是11个钩子,但我们经常谈论的是四个阶段,八个钩子

生命周期函数(钩子函数)

vue 框架内置函数,随着组件的生命周期,自动 按次序 执行

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

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

四个阶段:

  • 初始化 => 创建组件
graph TD
beforeCreate --> created
  • 挂载 => 渲染显示组件
graph TD
beforeMount --> mouted
  • 更新 => 修改了变量 => 触发视图刷新
graph TD
beforeUpdate --> updated
  • 销毁 => 切换页面 => 会把组件对象从内存删除
graph TD
beforeDestory --> destoryed

生命周期纵向图解.jpg

基本结构
<template>
  <div>
    <ul>
      <li v-for="(item, index) in arr" :key="index">{{ item.name }}</li>
    </ul>
    <p>{{text}}</p>
  </div>
</template>

<script>
export default {
  data () {
    return {
      text: "哈哈哈",
      arr: [{name:"haha",age:14,gender:"女"},
            {name:"yaya",age:20,gender:"男"},
            {name:"vava",age:4,gender:"女"},
            {name:"hehe",age:19,gender:"男"},]
    }
  },
 </script>

初始化

1.new Vue() 表示创建了一个Vue实例对象, const App=new Vue()

2.Init Events&Lifecycle
在这里Vue实例对象被初始化,只包含一些默认的生命周期和默认的方法

生命周期1: beforeCreate()

在beforeCreate生命周期执行的时候,data和methods中的数据都还没有被初始化 在这里想使用data和methods中的数据是获取不到的

  beforeCreate () {
    // 1. beforeCreate --- 实例初始化前
    console.log(this.text) // undefined
  },

3.Init injections&reactivity
在这里,data和methods被初始化

生命周期2:created()

created生命周期函数被执行的时候,就可以使用和操作data和methods了

created经常用于页面刚加载发送ajax请求数据

created () {
    // 2. created ---  实例初始化后=> 发送ajax请求
    console.log(this.text) // "哈哈哈"
}

挂载

如果Vue实例中没有配置el,则生命周期不会继续向下运行,直到挂载函数被执行,才会执行后续的生命周期

4-6 检测配置

image.png

这里表示Vue开始编译模版

最终在内存中生成一个编译好的模板字符串,然后把这个模版字符串,渲染为内存中的DOM,此时,渲染好的模板,只是在内存中,还没有真正挂载到页面中去

生命周期3:beforeMount()

beforeMount被执行的时候,模版已经在内存中被渲染好了,只是还没有挂载到浏览器界面中去

  beforeMount () {
    // 3. 挂载前:beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前
    console.log(document.querySelector("ul")) // null
    console.log(document.querySelector("ul").children[1].innerHTML) // 报错
  },

7.Create vm.$el and replace"el" with it
这一步,会将内存中渲染好的模板,真实的替换到浏览器中去

生命周期4:mounted()

mounted被执行的时候, vue的虚拟DOM, 挂载到真实的网页上

  mounted () {
    // 4. 挂载后=>mounted --- vue的虚拟DOM, 挂载到真实的网页上
    console.log(document.querySelector('ul').children[1].innerText)
  },

更新

运行阶段的生命周期函数只有两个,beforeUpdateupdated 这两个事件,会根据data数据的改变执行0次或者多次

当数据更新时,beforeUpdate开始

生命周期5: beforeUpdate ()

当执行beforeUpdate的时候,页面中显示的数据还是旧的,此时data数据是最新的,页面还没有和data保持同步

 beforeUpdate () {
    // 5. 更新前 => beforeUpdate --- 数据更新, 页面更新前
    // 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
    // console.log(document.getElementById("ul").children[4].innerHTML) // 报错
  },

8.Virtual DOMre-renderand patch
这一步执行的是:先根据data中的最新数据,在内存中重新渲染出一份最新的内存DOM树,
当最新的内存DOM树更新之后,会重新渲染到真实的页面中去,这时候,就完成了数据从data(model)层 ----> view(视图层)的更新

生命周期6: updated ()

执行updated的时候,页面的数据已经是最新的,和data保持同步了

  updated () {
    // 6. 更新后 => updated --- 数据更新, 页面更新后
    //点击新增数组元素,页面更新, 可以获取到新增的li标签
    console.log(document.getElementById("myUl").children[4].innerHTML)
  },

销毁

当vue的destroy函数被调用时,,开始进入到销毁阶段
(通过v-if的切换,可以触发子组件的destory)

生命周期7: beforeDestroy ()

当执行beforeDestroy钩子函数的时候,Vue实例就已经从运行阶段,进入到了销毁阶段;实例身上所有的data和所有的methods ,以及过滤器、指令.......都处于可用状态,此时,还没有真正执行销毁的过程

9.Teardown watchers, child components and event listeners
清除监视器、子组件和事件侦听器

生命周期8: destroyed ()

当执行到destroyed函数的时候,组件已经被完全销毁了,此时,组件中所有的数据、方法、指令、过滤器....都已经不可用了

点击按钮,通过isShow的true或者false来创建或销毁组件,从true到false就会执行beforeDestroy 和destroyed钩子


<template>
  <div>
    <MyCom v-if="isShow"/>
    <hr>
    <button @click="isShow = !isShow">销毁组件</button>
  </div>
</template>

<script>
import MyCom from './MyCom'
export default {
  data(){
    return {
      isShow: true
    }
  },
  components: {
    MyCom
  }
};
</script>

这就是vue组件的四个阶段八个钩子