Vue都使用那么久了,还不了解它的生命周期吗✨

简介: 我记得尤大曾经说过,你看Vue源码干嘛?你使用Vue又不需要它的源码,你只需要会用就行了!但是我们得卷啊,不卷怎么脱颖而出😥,我还记得在今年的蓝桥杯群里,有一同届的还不知道哪个大学的哥们,已经在读Vue/React/Node的源码了.....作为小菜鸡的我看着大佬侃侃而谈,在群角落里瑟瑟发抖。
大家好,我是Ned👀,一个刚刚入门前端未满两年的大三小学生🌹

未来路还长🎉, 一起努力加油吧❤~

前言

我记得尤大曾经说过,你看Vue源码干嘛?你使用Vue又不需要它的源码,你只需要会用就行了!

但是我们得卷啊,不卷怎么脱颖而出😥,我还记得在今年的蓝桥杯群里,有一同届的还不知道哪个大学的哥们,已经在读Vue/React/Node的源码了.....作为小菜鸡的我看着大佬侃侃而谈,在群角落里瑟瑟发抖。

image.png

最近有在牛客上复习Vue的知识,整理出这篇文章,一是方便自己未来复习,二是希望能够帮助一些跟我一样的朋友们复习一边知识点,学习在什么时候都不晚。

这篇文章会讲到:

  • Vue的生命周期到底是什么
  • Vue生命周期的执行顺序
  • 生命周期的每个阶段适合做什么
  • 我们的请求放在哪个生命周期会更合适
当然我只会讲我理解的emm,可能会很浅,还请多包涵。

Vue的生命周期到底是什么?

与其说是Vue的生命周期,我觉得不如说是其内组件的生命周期。
简单来说,它的生命周期就是用来描述一个组件从引入到退出的全过程。
那复杂来说呢?就是一个组件从创建开始经历了数据初始化挂载更新等步骤后,最后被销毁

Vue生命周期的执行顺序

他整体是分为三个大阶段的,在三个大阶段中,有细分为若干的小阶段。我们可以在不同的阶段去做不同的事情,后文也会讲到不同的阶段适合我们去做具体什么事情的。
image.png
我们先来看看它的执行顺序吧:

有两种方法,一种就是Vue的官方文档上面有一个图是专门解释生命周期的,但鉴于可能许多小伙伴们都是跟我一样,看英文文档都要伴随着翻译的水平,所以特意在网上找了个翻译过后的汉化版,放在这里给大家做参考:

生命周期.webp
这个图详细的解释了一个Vue实例从创建到销毁的全过程。

第二种方法,就是我们在Vue项目中打印一下,在控制台中我们就能清晰的看出,谁执行的早,谁执行的晚,甚至能看出他们有什么区别:

beforeCreate: function () {
        console.group('------beforeCreate创建前状态------');
        console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
        console.log("%c%s", "color:red", "data   : " + this.$data); //undefined 
        console.log("%c%s", "color:red", "message: " + this.message)
    },
    created: function () {
        console.group('------created创建完毕状态------');
        console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
        console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化 
        console.dir(this.$data)
        console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
    },
    beforeMount: function () {
        console.group('------beforeMount挂载前状态------');
        console.log("%c%s", "color:red", "el     : " + (this.$el)); //undefined
        console.dir(this.$el)
        console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化  
        console.log("%c%s", "color:red", "message: " + this.message); //已被初始化  
    },
    mounted: function () {
        console.group('------mounted 挂载结束状态------');
        console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
        console.dir(this.$el)
        console.log("%c%s", "color:red", "data   : " + this.$data); //已被初始化
        console.dir(this.$data)
        console.log("%c%s", "color:red", "message: " + this.message); //已被初始化 
    },
    beforeUpdate: function () {
        console.group('beforeUpdate 更新前状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el);
        console.dir(this.$el)
        console.log("%c%s", "color:red", "data   : " + this.$data);
        console.dir(this.$data)
        console.log("%c%s", "color:red", "message: " + this.message);
    },
    updated: function () {
        console.group('updated 更新完成状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el);
        console.dir(this.$el)
        console.log("%c%s", "color:red", "data   : " + this.$data);
        console.dir(this.$data)
        console.log("%c%s", "color:red", "message: " + this.message);
    },
    beforeDestroy: function () {
        console.group('beforeDestroy 销毁前状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el);
         console.dir(this.$el)
        console.log("%c%s", "color:red", "data   : " + this.$data);
        console.dir(this.$data)
        console.log("%c%s", "color:red", "message: " + this.message);
    },
    destroyed: function () {
        console.group('destroyed 销毁完成状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el);
         console.dir(this.$el)
        console.log("%c%s", "color:red", "data   : " + this.$data);
        console.dir(this.$data)
        console.log("%c%s", "color:red", "message: " + this.message)
    }

挂载阶段

其实这个代码的先后顺序就是他执行的先后顺序了,为了能有更新的状态,所以我找了个todolist的demo,可以添加跟删除的,方便我们来看,首先是刚进入页面:

image.png
我们可以看到beforeCreate是最先的,并且在此时的状态下,我们打印的信息什么都拿不到。

之后进入了created状态,在这个状态中我们的el,也就是Dom元素依旧是拿不到的,但是我们已经可以拿到data了,这意味着 created已经将数据加载进来了 ,已经为这个Vue实例开辟了内存空间。

beforeMount,挂载前状态,在我的理解挂载就是将虚拟Dom转变成真实Dom的过程,所以在这之前,我们的el当然还是拿不到的。

mounted,挂载结束,意味着虚拟Dom已经挂载在了真实的元素上,所以从此开始我们就可以拿到el了。我们可以用console.dir去打印一些我们需要的元素的属性。

至此,我们的挂载阶段就结束了。

更新阶段

下面我们删除一个list,来看一下更新状态。

更新状态.gif

每当我们去改变页面元素的时候,就会进入更新阶段,也就是beforeUpdate,updated这两个状态。

销毁阶段

下面我们再来看一下最后的销毁阶段。

销毁状态.gif

beforeDestroy,销毁前状态,在销毁之前,所以我们的元素、data都是如同挂载之后的阶段一样,都是可以打印出来的。

destroyed,其实最让我震惊的是这个,销毁完成的状态,我以为销毁了,那应该什么都打印不出来了,其实不然,他还是什么都可以打印出来的。

beforeDestroydestroyed,都是我们离开这个组件才会被调用的生命周期。

生命周期的每个阶段适合做什么

下面我们来讲讲,在不同的阶段我们可以做些什么:

created:
在Vue实例创建完毕状态,我们可以去访问data、computed、watch、methods上的方法和数据,但现在还没有将虚拟Dom挂载到真实Dom上,所以我们在此时访问不到我们的Dom元素(el属性,ref属性此时都为空)。

我们在此时可以进行一些简单的Ajax,并可以对页面进行初始化之类的操作

beforeMount:
它是在挂载之前被调用的,会在此时去找到虚拟Dom,并将其编译成Render

mounted:
虚拟Dom已经被挂载到真实Dom上,此时我们可以获取Dom节点,$ref在此时也是可以访问的。

我们在此时可以去获取节点信息,做Ajax请求,对节点做一些操作

beforeupdate:
响应式数据更新的时候会被调用,beforeupdate的阶段虚拟Dom还没更新,所以在此时依旧可以访问现有的Dom。

我们可以在此时访问现有的Dom,手动移除一些添加的监听事件

updated:
此时补丁已经打完了,Dom已经更新完毕,可以执行一些依赖新Dom的操作。

但还是不建议在此时进行数据操作,避免进入死循环(这个坑我曾经踩过)

beforeDestroy:
在Vue实例销毁之前被调用,在此时我们的实例还未被销毁。

在此时可以做一些操作,比如销毁定时器,解绑全局事件,销毁插件对象等

父子组件的生命周期

刚刚说的都是单页面,那么父子组件的生命周期会是什么样子呢?我们仅做一个简单的补充。

不知道大家在刚刚的图中是否注意到了这两行:

image.png

我们页面中的小li就是一个被嵌入在这个大页面内部的一个子组件,我们也打印了它的生命周期:

created() {
        console.log('list created')
    },
    mounted() {
        console.log('list mounted')
    },
    beforeUpdate() {
        console.log('list before update')
    },
    updated() {
        console.log('list updated')
    },
    beforeDestroy() {
        // 及时销毁,否则可能造成内存泄露
        console.log('list beforeDestroy')
    },
    destroyed(){
        console.log('list Destroy')
    }

由此可得,在父组件挂载前阶段,子组件已经挂载完成了。

不光是挂载阶段,其他两个阶段我们也可以打印出来,但是在这里我就不细说了,直接上结论:

  • 挂载阶段:父组件 beforeMount -> 子组件 created -> 子组件 mounted -> 父组件 mounted
  • 更新阶段:父组件 beforeUpdate -> 子组件 beforeUpdate -> 子组件 updated -> 父组件 updated
  • 销毁阶段:父组件 beforeDestroy -> 子组件 beforeDestroy -> 子组件 destroyed -> 父组件 destroyed

我们的请求放在哪个生命周期会更合适

那么至此我们已经对于Vue的生命周期有了一个基本的了解,现在我们来说一说,我们的请求应该放到哪个生命周期中才最为合适。

一般来说,会有两种回答:createdmounted
上文已经讲了,这两个回答,前者是数据已经准备好了,后者是连dom也已经加载完成了,那么到底哪个才是正确答案呢?

其实,两个都是可以的,但是mounted会更好。

可能有人会说: created的时间会更早,早些调用不是会省很多时间吗?这样性能会不会更高一点

别急,我们一点一点来看

  • 首先,它确实是早了,但是早不了几微秒,所以这其实没有提高性能
  • 其次,我们在created阶段并没有去做渲染,所以在接下来我们会去做Dom渲染,但是如果此时我们还做了Ajax操作,在Ajax结束之后就会返回数据,我们就会将其插入到主线程中去运行,去处理数据,但是我们要知道,在浏览器机制中,渲染线程跟js线程是互斥的,所以有可能我们做渲染的同时,另一边可能要处理Ajax返回的数据了,这时候渲染就有可能被打断,在处理完数组后,去进行重新渲染。

那如果在created中有多个Ajax呢?我们又要重新进行渲染,所以在created去做Ajax请求这明显不太合适。

  • 还有,有的时候我们接到返回的数据的时候可能要在回调函数中去进行一些Dom的操作,可是created阶段我们还没有将真实Dom加载出来,所以相对而言我们还是在mounted去调用要好一些
如果是服务端渲染,我们将其放入 created中进行,因为服务端不支持 mounted

写在最后

Vue算是前端学习旅途上陪伴我最长的东西了,但是至今还是没有将其学明白hhhh。

要更加努力呀,加油~
相关文章
|
2月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
228 2
|
11天前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
221 137
|
5月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
660 0
|
5月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
4月前
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
165 0
|
4月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
323 1
|
5月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
417 17
|
5月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
241 1
|
5月前
|
存储 JavaScript 前端开发
如何高效实现 vue 文件批量下载及相关操作技巧
在Vue项目中,实现文件批量下载是常见需求。例如文档管理系统或图片库应用中,用户可能需要一次性下载多个文件。本文介绍了三种技术方案:1) 使用`file-saver`和`jszip`插件在前端打包文件为ZIP并下载;2) 借助后端接口完成文件压缩与传输;3) 使用`StreamSaver`解决大文件下载问题。同时,通过在线教育平台的实例详细说明了前后端的具体实现步骤,帮助开发者根据项目需求选择合适方案。
423 0
|
5月前
|
JavaScript 前端开发 UED
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
181 0
下一篇
开通oss服务