一文教你搞懂Vue生命周期

Vue生命周期

生命周期示意图

img

Vue 实例生命周期

Vue3

组件生命周期图示

组件创建阶段

  • new vue

    new一个vue的实例对象;此时会进入组件的创建过程(该组件在代码中被注册并使用时,就代表着其被new了一个新的实例对象)。

  • Init Events & Lifecycle

    初始化组件的事件和生命周期函数;当执行完这一步之后,组件的生命周期函数就已经全部初始化好了,等待着依次去调用。

  • beforeCreate (服务端渲染可用

    (初始化一个空的 Vue 实例),组件的props,data和methods以及页面DOM结构,都还没有初始化

    在实例初始化之后,进行数据侦听事件/侦听器的配置之前同步调用

  • Init injections & reactivity

    这个阶段中,正在初始化props,computed, data和methods中的数据以及方法。

    在creted之前就会行初始化 computed 和 watch

  • created(服务端渲染可用

    Vue 实例初始化完成,props data methods 都已初始化完成,可调用。但尚未开始渲染模板。

    在实例创建完成后被立即同步调用。在这一步中,实例已完成对选项的处理,意味着以下内容已被配置完毕:数据侦听计算属性方法事件/侦听器的回调函数。然而,挂载阶段还没开始,且 $el property 目前尚不可用。

  • 判断是否有el,template,然后进行编译

    正在解析模板结构,把data上的数据拿到,并且解析执行模板结构汇总的指令;当所有指令被解析完毕,那么模板页面就被渲染到内存中了;当模板编译完成,我们的模板页面,还没有挂载到页面上,只是存在于内存中,用户看不到页面;

image-20240308101931045

优先级顺序:el < template < render

el对应的HTML元素是写在网页上的。

//1、el,template,render(渲染函数)都是vue对象对应的HTML元素(DOM对象)
//2、优先级顺序:el < template < render
//3、el对应的HTML元素是写在网页上的。
 
 
HTML代码:
 
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<span>我今年{{age}}岁了</span>
		</div>
	</body>
</html>
<script type="text/javascript" src="js/vue.min.js" ></script>
//1、只有el
let vm = new Vue({
	el:"#app",
	data:{
		age:12
	}
});
2、只有template,是不行的,因为,vue对象不知道把template放在何处;
3、只有render(渲染)函数,也是不行的,因为,vue对象不知道把render后的结果放在何处;
4、既有el又有template,就会用template里的内容替换el的outHTML。
 
let vm = new Vue({
	el:"#app",
	template:"<div><p>我template出来的,年龄{{age}}</p></div>",
	data:{
		age:12
	}
});
查看elements:
 
发现 id为app的div没有了
 
 
5、既有el又有template,又有render函数。就会使用render函数的内容,因为它的优先级高。
//   但是此时,“Mustache”语法 (双大括号)没法使用,
//   因为,vue只是把render函数的返回值放在HTML里,而不进行再次的绑定
//   render函数就是让你发挥 JavaScript 最大的编程能力。
 
let vm = new Vue({
	el:"#app",
	template:"<div><p>我template出来的,年龄{{age}}</p></div>",
	data:{
		age:12
	},
	render:function(createElement){
	  // return createElement('h1', '我是render出来的HTML,年龄{{age}}');//不能使用“Mustache”语法 (双大括号)
	   return createElement('h1', '我是render出来的HTML,年龄'+this.age);
	}
});
查看elements:
 
发现 id为app的div没有了,template属性的值也没有起作用,只显示了render函数的返回值。
  • beforeMount

    编译模板,调用 render 函数生成 vdom ,但还没有开始渲染 DOM

  • 创建并替换

    这一步把正在内存中渲染好的模板结构替换掉el属性指定的DOM元素

  • mounted

    渲染 DOM 完成,页面更新。组件创建完成,开始进入运行阶段。

    注意 mounted 不会保证所有的子组件也都被挂载完成。如果你希望等到整个视图都渲染完毕再执行某些操作,可以在 mounted 内部使用 vm.$nextTick:

组件运行阶段

  • beforeUpdate

    data中的数据,已经是最新的数据了。但是,页面上渲染的数据,还是之前的旧数据

    在数据发生改变后,DOM 被更新之前被调用。这里适合在现有 DOM 将要被更新之前访问它,比如移除手动添加的事件监听器。

  • virtual DOM re-render and patch

    正在根据最新的data数据,重新渲染内存中的的DOM结构;并把渲染好的模板结构替换到页面上

  • updated

    在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用。

    注意,尽量不要在 updated 中继续修改数据,否则可能会触发死循环。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。

    注意,updated 不会保证所有的子组件也都被重新渲染完毕。如果你希望等到整个视图都渲染完毕,可以在 updated 里使用 vm.$nextTick:

  • activated/onActivated

    keep-alive 缓存的组件激活时调用。

  • deactived/onDeactivated

    keep-alive 缓存的组件停用时调用。

组件销毁阶段

  • beforeDestory/beforeUnmount

    组件进入销毁阶段。组件即将被销毁,但是还没有真正开始销毁,此时组件还是正常可用的;data、methods等数据或方法,依旧可以被正常访问。

    卸载组件实例后调用,在这个阶段,实例仍然是完全正常的。

    移除、解绑一些全局事件、自定义事件,可以在此时操作。

  • 销毁过程

    销毁组件的数据侦听器,子组件,事件监听

  • destoryed/unmounted

    卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。

2.5.0+新增errorCaptured

  • 类型(err: Error, vm: Component, info: string) => ?boolean

  • 详细

    在捕获一个来自后代组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

当捕获一个来自子孙组件的错误时被调用

如何正确的操作 DOM

mountedupdated 都不会保证所有子组件都挂载完成,如果想等待所有视图都渲染完成,需要使用 $nextTick

mounted() {
  this.$nextTick(function () {
    // 仅在整个视图都被渲染之后才会运行的代码
  })
}

ajax 放在哪个生命周期合适?

一般有两个选择:createdmounted ,建议选择后者 mounted

执行速度

  • 从理论上来说,放在 created 确实会快一些
  • 但 ajax 是网络请求,其时间是主要的影响因素。从 createdmounted 是 JS 执行,速度非常快。
  • 所以,两者在执行速度上不会有肉眼可见的差距

代码的阅读和理解

  • 放在 created 却会带来一些沟通和理解成本,从代码的执行上来看,它会一边执行组件渲染,一边触发网络请求,并行
  • 放在 mounted 就是等待 DOM 渲染完成再执行网络请求,串行,好理解

所以,综合来看,更建议选择 mounted

Composition API 生命周期有何不同

  • setup 代替了 beforeCreatecreated
  • 生命周期换成了函数的形式,如 mounted -> onMounted 参考 https://v3.cn.vuejs.org/api/composition-api.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90
import { onUpdated, onMounted } from 'vue'

export default {
    setup() {
        onMounted(() => {
            console.log('mounted')
        })
        onUpdated(() => {
            console.log('updated')
        })
    } 
}

computed 初始化在什么时候?

props,methods,data和computed,watch的初始化都是在beforeCreated和created之间完成的

watch,immediate为true触发时机

immediate如果为true, 也是发生在beforeCreate 之后,created之前

父子组件的生命周期顺序

加载渲染过程 :

  • 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子组件更新过程:

  • 父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程:

  • 父beforeUpdate->父updated

销毁过程:

  • 父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

父子组件及mixin的生命周期执行顺序:

  • mixin的beforeCreate > 父beforeCreate > mixin的created > 父created > mixin的beforeMount > 父beforeMount > 子beforeCreate > 子created > 子beforeMount > 子mounted > mixin的mounted >父mounted

image-20240308113947100

image-20240308113717011

<template>
  <div>
    <div ref="div">父组件</div>
    <input type="text" v-model="msg">
    <div>{{newMsg}}</div>
    <hr>
    <child :msg="msg"></child>
  </div>
</template>

<script>
import Child from './Child.vue'
export default {
  name: 'ParentDemo',
  components: {
    Child
  },
  data() {
    return {
      msg: '父组件的数据'
    }
  },
  beforeCreate() {
    console.log('父beforeCreate', this.msg)
  },
  created() {
    console.log('父created', this.msg)
  },
  beforeMount() {
    console.log('父beforeMount', this.$refs.div)
  },
  mounted() {
    console.log('父mounted', this.$refs.div)
  },
  beforeUpdate() {
    console.log('父beforeUpdate', this.$refs.div.innerHTML)
  },
  updated() {
    console.log('父updated', this.$refs.div.innerHTML)
  },
  activated() {
    console.log('父activated')
  },
  deactivated() {
    console.log('父deactivated')
  },
  beforeDestroy() {
    console.log('父beforeDestroy')
  },
  destroyed() {
    console.log('父destroyed')
  },
  errorCaptured() {
    console.log('父errorCaptured')
  },
  computed: {
    newMsg() {
      return this.msg + 'computed'
    }
  },
  watch: {
    msg: {
      handler(newVal, oldVal) {
        console.log('父watch', newVal, oldVal)
      },
      immediate: true
    }
  }
}
</script>

Child.vue

<template>
  <div>
    <div>子组件</div>
    <p>父组件传递过来的数据:{{msg}}</p>
  </div>
</template>

<script>
export default {
  name: 'ChildDemo',
  props: ['msg'],
  beforeCreate() {
    // 这里获取不到this.msg,获取会报错
    console.log('子beforeCreate')
  },
  created() {
    console.log('子created', this.msg)
  },
  beforeMount() {
    console.log('子beforeMount')
  },
  mounted() {
    console.log('子mounted')
  },
  beforeUpdate() {
    console.log('子beforeUpdate')
  },
  updated() {
    console.log('子updated')
  },
  activated() {
    console.log('子activated')
  },
  deactivated() {
    console.log('子deactivated')
  },
  beforeDestroy() {
    console.log('子beforeDestroy')
  },
  destroyed() {
    console.log('子destroyed')
  },
  errorCaptured() {
    console.log('子errorCaptured')
  }
}
</script>

上源码

beforeCreate->created之间做的事

  • inject
  • state (props,methods,computed,watched)
  • provide

vue/src/core/instance

image-20240308123420608

init.ts

image-20240308124238408

inject.ts

image-20240308124448616

state.ts

image-20240308124605288

inject.ts

image-20240308124708944

参考文章

  • vue 自省知识点——生命周期

  • Vue中的computed是在生命周期的哪个阶段执行的?

  • Vue组件的生命周期

  • vue中el属性…

  • vue2,最重要的还是官网啊啊啊

  • vue3官网相关解释

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/439791.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【python爬虫】免费爬取网易云音乐完整教程(附带源码)

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 所属专栏:爬虫实战,零基础、进阶教学 景天的主页:景天科技苑 文章目录 网易云逆向网易云逆向 https://music.163.com/ 下载云音乐 胡广生等,可以选择自己喜欢的歌曲 首先,我们可以先根据…

爬虫入门到精通_框架篇15(Scrapy框架安装)

1 Scrapy安装 Scrapy的安装有多种方式&#xff0c;它支持Python2.7版本及以上或Python3.3版本及以上。下面说明Python3环境下的安装。 Scrapy依赖的库比较多&#xff0c;至少需要依赖库有Twisted14.0,lxml 3.4,pyOpenSSL 0.14。而在不同平台环境又各不相同&#xff0c;所以在安…

如何更改照片分辨率?图片分辨率在线修改方法

当我们需要打印照片时&#xff0c;可能需要调整照片的dpi值以适应特定的打印设备和输出质量需求。较高的dpi值可以提供更好的打印质量和细节&#xff0c;而较低的dpi值可以减小打印文件的大小&#xff0c;如何更改照片分辨率呢&#xff1f;想要改图片分辨率的话可以试试本文分享…

LORA: LOW-RANK ADAPTATION OF LARGE LAN-GUAGE MODELS

TOC 1 前言2 方法2.1 LOW-RANK-PARAMETRIZED UPDATE MATRICES 1 前言 1) 提出背景 大模型时代&#xff0c;通常参数都是上亿级别的&#xff0c;若对于每个具体任务都要去对大模型进行全局微调&#xff0c;那么算力和资源的浪费是巨大的。 根据流形学习思想&#xff0c;对于数…

专题一 -双指针 - leetcode 611. 有效三角形的个数 | 中等难度

leetcode 611. 有效三角形的个数 leetcode 611. 有效三角形的个数 | 中等难度1. 题目详情1. 原题链接2. 基础框架 2. 解题思路1. 题目分析2. 算法原理3. 时间复杂度 3. 代码实现4. 知识与收获 leetcode 611. 有效三角形的个数 | 中等难度 1. 题目详情 给定一个包含非负整数的…

基于SSM技术的分布式销售平台设计与实现

目 录 摘 要 I Abstract II 1 绪论 1 1.1 课题研究背景与意义 1 1.2 国内外研究现状 1 1.2.1 国外研究现状 1 1.2.2 国内研究现状 2 1.3 本章小结 2 2 工程开发技术介绍 3 2.1 Web前端技术栈 3 2.1.1 HTML&CSS 3 2.1.2 jQuery 3 2.1.3 JSP 3 2.2 服务端开发技术栈 3 2.2.1…

ChatGPT 升级出现「我们未能验证您的支付方式/we are unable to authenticate」怎么办?

ChatGPT 升级出现「我们未能验证您的支付方式/we are unable to authenticate」怎么办&#xff1f; 在订阅 ChatGPT Plus 时&#xff0c;有时候会出现以下报错 &#xff1a; We are unable to authenticate your payment method. 我们未能验证您的支付方式。 出现 unable to a…

基于apicloud+vue的汽车服务系统设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 课题背景 3 1.1 课题的研究背景与意义 3 1.2研究现状 3 1.3本章小结 4 2 系统开发相关技术 5 2.1 ApiCloud开发工具 5 2.2 MVC架构模型 5 2.3 MySQL数据库 5 2.4 Hibernate、Spring框架 6 2.5 本章小结 6 3 系统分析 7 3.1 系统需求分析 …

Uber/Google Golang编码标准深度分析

良好的代码风格对于开发优秀的产品至关重要&#xff0c;本文通过分析比较三部流传甚广的Golang代码风格指南&#xff0c;介绍了Go代码风格要点&#xff0c;并介绍了通过工具实现代码检查的方式。原文: Mastering Go: In-Depth Analysis of Uber and Google’s Coding Standards…

启动vue项目执行npm run serve报错 : error in ./src/element-variables.scss

error in ./src/element-variables.scss 问题原因 node-sass的版本问题 解决方式 我直接更新了一下node-sass&#xff0c;就好了 npm install node-sass 再次执行就可以执行成功了

双色球选号 python

题目描述 编写一个能实现双色球选号的小程序。双色球选号由7个数字组成&#xff0c;其中有6个红球&#xff0c;其号码的取值范围为[1,33];一个蓝球的取值范围为[1,16],要求6个红球从小到大排列&#xff0c;蓝球在最后输出。其输出格式为09 12 16 20 30 33 | 03。&#xff08;注…

SpringMVC03、HelloSpring

3、HelloSpring 3.1、配置版 新建一个Moudle &#xff0c; springmvc-02-hello &#xff0c; 添加web的支持&#xff01; 确定导入了SpringMVC 的依赖&#xff01; 配置web.xml &#xff0c; 注册DispatcherServlet <?xml version"1.0" encoding"UTF-8…

软件工程顶会——ICSE '24 论文清单、摘要

1、A Comprehensive Study of Learning-based Android Malware Detectors under Challenging Environments 近年来&#xff0c;学习型Android恶意软件检测器不断增多。这些检测器可以分为三种类型&#xff1a;基于字符串、基于图像和基于图形。它们大多在理想情况下取得了良好的…

Vue时间轴

之前有这样子的需求没有用第三方插件于是自己写一个简单的时间轴 时间轴滚动条并左右切换滚动条位置相对应移动 <div class"time-scrollbar"><div v-if"timeLineData.length>0" class"scrollbar-content"><div class"ar…

基于FastAPI构造一个AI模型部署应用

前言 fastapi是目前一个比较流行的python web框架&#xff0c;在大模型日益流行的今天&#xff0c;其云端部署和应用大多数都是基于fastapi框架。所以掌握和理解fastapi框架基本代码和用法尤显重要。 需要注意的是&#xff0c;fastapi主要是通过app对象提供了web服务端的实现代…

Java+SpringBoot+Vue+MySQL实战:打造智能餐厅点餐系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

图机器学习(3)-连接层面的特征工程

0 问题定义 通过已经连接去猜未知连接&#xff1a; 有两个思路&#xff1a;

基于FPGA加速的bird-oid object算法实现

导语 今天继续康奈尔大学FPGA 课程ECE 5760的典型案例分享——基于FPGA加速的bird-oid object算法实现。 &#xff08;更多其他案例请参考网站&#xff1a; Final Projects ECE 5760&#xff09; 1. 项目概述 项目网址 ECE 5760 Final Project 模型说明 Bird-oid object …

基于springboot实现大学生兼职网站系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现大学生兼职系统演示 摘要 现代化的市场中&#xff0c;人们日常的工作、生活都在不断的提速&#xff0c;而人们在工作与生活中与互联网的结合也越来越紧密&#xff0c;通过与互联网紧密的结合可以更好地实现日常工作的线上化、信息化、便捷化。现如今的各行各…

案例研究|辛格林电梯借助DataEase实现数据整合与智能展示

辛格林电梯&#xff08;SIGLEN&#xff09;于2012年创立&#xff0c;是电梯领域的领军品牌之一。该公司总部位于广东佛山&#xff0c;是全国首批获得A1级电梯制造资质的企业&#xff0c;拥有省级工程技术研究中心。辛格林电梯专注于研发和生产高品质电梯产品&#xff0c;涵盖别…