Vue.js学习笔记——17.Vue的生命周期

本文详细介绍了Vue实例的生命周期,包括创建、挂载、运行和销毁四个阶段的钩子函数及其作用,并通过代码示例展示了如何在各个阶段操作。同时,探讨了父子组件的生命周期执行顺序,特别是在创建、更新和销毁阶段的不同。了解这些知识对于优化Vue应用性能和处理组件间的交互至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Vue实例的生命周期

生命周期即是一个事物从出生到消亡的过程,世间万物都有生命周期,Vue实例也是如此。Vue的生命周期是Vue中比较重要的知识点,在面试中常常被问到。
简单来说可以分为四个阶段:创建阶段,挂载阶段,运行阶段,销毁阶段。在这个过程中会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
每个阶段都有两个生命周期钩子函数:

  • 创建阶段–beforeCreate,created
  • 挂载阶段–beforeMount,mounted
  • 运行阶段–beforeUpdate,updated
  • 销毁阶段–beforeDestroy,destroyed

通过官方的图可以直观的看到这几个阶段 Vue 帮我们做了什么,以及我们又能在不同阶段做些什么:
生命周期

创建阶段

此时Vue刚刚出生,组件开始初始化并且开始观察数据,此阶段有beforeCreate 和 created 两个生命周期钩子函数。

beforeCreate

是new Vue()之后触发的第一个钩子,此时 data、methods、computed以及watch上的数据和方法还未初始化,都不能被访问。

created

在实例创建完成后被立即调用,此时已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数。然而,挂载阶段还没开始,$el property 目前尚不可用,所以无法与Dom进行交互。

挂载阶段

这个阶段是vue实例的出生阶段,这个阶段将实现 DOM 的挂载,这标志着我们可以在浏览器里中看到页面了。

beforeMount

发生在挂载之前,在这之前 template 模板已导入渲染函数编译。此时虚拟Dom已经创建完成,即将开始渲染,此时页面仍是空白。在这一阶段也可以对数据进行更改,不会触发updated。

mounted

在挂载完成后发生,此时真实的Dom挂载完毕,vue实例已经初始化完成,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。

运行阶段

当vue实例中的数据发生改变时,DOM 也会发生变化,此阶段中Vue将持续监听数据,随时渲染并更新DOM。

beforeUpdate

发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重新渲染,但会再次触发当前钩子函数。

updated

发生在更新完成之后,此时 Dom 已经更新。现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,最好使用计算属性或 watcher 取而代之。最好不要在此期间更改数据,因为这可能会导致无限循环的更新。

销毁阶段

一旦$destory()被调用,Vue实例进入消亡阶段,实例还可以被使用,直到destroyed(),我们可以为Vue实例处理一些“后事”。

beforeDestroy

发生在实例销毁之前,在这期间实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。

destroyed

发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,事件监听器被移除,所有子实例也统统被销毁。

以上就是Vue的整个生命周期,可以写个简单的例子验证一下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <button @click="update">更新</button>
  <button @click="destroy">销毁</button>
  <div>{{msg}}</div>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      msg:"marmot"
    },
    methods: {
      update() {
        this.msg = '土拨鼠'
      },
      destroy() {
        this.$destroy()
      }
    },
    beforeCreate() {
      console.log('beforeCreate执行');
    },
    created() {
      console.log('created执行');
    },
    beforeMount() {
      console.log('beforeMount执行');
    },
    mounted() {
      console.log('mounted执行');
    },
    beforeUpdate() {
      console.log('beforeUpdate执行');
    },
    updated() {
      console.log('updated执行');
    },
    beforeDestroy() {
      console.log('beforeDestroy执行');
    },
    destroyed() {
      console.log('destroyed执行');
    }
  })
</script>
</body>
</html>

执行结果:
栗子

二、父子组件的生命周期

Vue单个组件的生命周期我们已经了解了,但是,如果有嵌套组件,父子组件的生命周期的执行顺序又有稍许不同。

创建与挂载阶段

该过程主要涉及 beforeCreate、created、beforeMount、mounted 4 个钩子函数。
当父组件执行完beforeMount挂载开始后,会依次执行子组件中的钩子,直到全部子组件mounted挂载到实例上,父组件才会进入mounted钩子
执行顺序为:
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
一定得等所有子组件挂载完毕后,父组件才能挂载完毕,所以父组件的 mounted 在最后。

更新阶段

该过程主要涉及 beforeUpdate、updated 2 个钩子函数。注意,当父子组件有数据传递时,才有这个更新阶段执行顺序的比较。
执行顺序为:
父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated

销毁阶段

该过程主要涉及beforeDestroy、destroyed 2 个钩子函数。
执行顺序为:
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed

这里用项目的单文件组件的形式举个例子:

<!-- App.vue -->
<template>
  <div id="app">
    <button @click="update">更新</button>
    <button @click="destroy">销毁</button>
    <my-cpn :msg="msg"></my-cpn>
  </div>
</template>

<script>
import MyCpn from "./components/MyCpn.vue";
export default {
  name: "App",
  components: {
    MyCpn,
  },
  data() {
    return {
      msg:'marmot'
    }
  },
  methods: {
    update() {
      this.msg = "土拨鼠";
    },
    destroy() {
      this.$destroy();
    },
  },
  beforeCreate() {
    console.log("父组件beforeCreate执行");
  },
  created() {
    console.log("父组件created执行");
  },
  beforeMount() {
    console.log("父组件beforeMount执行");
  },
  mounted() {
    console.log("父组件mounted执行");
  },
  beforeUpdate() {
    console.log("父组件beforeUpdate执行");
  },
  updated() {
    console.log("父组件updated执行");
  },
  beforeDestroy() {
    console.log("父组件beforeDestroy执行");
  },
  destroyed() {
    console.log("父组件destroyed执行");
  },
};
</script>

<style>
</style>
<!-- MyCpn.vue -->
<template>
  <p>{{ msg }}</p>
</template>

<script>
export default {
  props: {
    msg: String,
  },
  beforeCreate() {
    console.log("子组件beforeCreate执行");
  },
  created() {
    console.log("子组件created执行");
  },
  beforeMount() {
    console.log("子组件beforeMount执行");
  },
  mounted() {
    console.log("子组件mounted执行");
  },
  beforeUpdate() {
    console.log("子组件beforeUpdate执行");
  },
  updated() {
    console.log("子组件updated执行");
  },
  beforeDestroy() {
    console.log("子组件beforeDestroy执行");
  },
  destroyed() {
    console.log("子组件destroyed执行");
  },
};
</script>

<style>
</style>

执行结果:
父子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值