vue用了这么久,你还不了解它的生命周期吗?你不需要它的源代码来使用Vue,你只需要知道如何使用它!但是我们要滚,不滚怎么能出人头地呢?还记得今年的蓝桥杯组,有一个同校的小伙伴,不知道是哪个大学的。他已经在看Vue/React/Node的源码了。。。。作为一个菜鸟,看着大佬说话,在群里的角落瑟瑟发抖。最近在牛客上复习了Vue的知识点,特整理了这篇文章,一是方便自己以后复习,二是帮助一些像我这样的朋友复习知识点,学什么都不晚。这篇文章会讲:什么是Vue的生命周期Vue生命周期的执行顺序是什么?生命周期的每个阶段适合做什么?哪个生命周期更适合我们的要求?当然我只说我理解的emm。它可能很浅,所以请耐心等待。Vue的生命周期到底是什么?与其说是Vue的生命周期,不如说是它的组件的生命周期。简单的说,它的生命周期就是用来描述一个组件从引入到退出的全过程。复杂度如何?表示一个组件从创建开始,经历了数据初始化、挂载、更新等步骤,最后被销毁。Vue生命周期的执行顺序整体分为三大阶段。在三大阶段中又细分为若干小阶段。不同的阶段我们可以做不同的事情,后面会讲到不同的阶段具体适合我们做什么事情。先来看看它的执行顺序:有两种方法,一种是vue的官方文档中有一张图专门解释了生命周期,不过可能很多朋友和我一样,看英文文档肯定是伴随着翻译的水平,特意在网上找了一个中文翻译版,放在这里供大家参考:这张图详细解释了一个Vue实例从创建到销毁的全过程。第二种方法是我们在vue项目中打印出来。在控制台中,我们可以清楚的看到谁先执行,谁执行晚,甚至可以看出他们之间的区别:beforeCreate:function(){console.group('------beforeCreatestate------');console.log("%c%s","color:red","el:"+this.$el);//undefinedconsole.log("%c%s","color:red","data:"+this.$data);//undefinedconsole.log("%c%s","color:red","message:"+this.message)},created:function(){console.group('------created创建地位---');console.log("%c%s","color:red","el:"+this.$el);//undefinedconsole.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));//undefinedconsole.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);},更新:function(){console.group('更新的更新更新完成状态================red","el:"+this.$el);console.dir(this.$el)console.log("%c%s","color:red","data:"+this.$data);console.dir(this.$data)控制台le.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)}复制代码mount阶段其实这段代码的顺序是它的执行顺序。为了有一个更新的状态,我找到了一个todolist的demo,可以添加和删除。方便我们看,首先,直接进入页面即可:我们可以看到beforeCreate是第一个,在这个状态下,我们是获取不到任何打印信息的,然后进入created状态。在这个状态下,我们的el,也就是Dom元素,我们还拿不到,但是我们已经可以拿到数据了,也就是说created已经把数据加载进去了,并且已经为这个vue实例开辟了内存空间.beforeMount,挂载前的状态,在我的理解中,挂载就是将虚拟Dom转化为真实Dom的过程,所以在这之前,当然我们的el还是不可用的。mounted,mount结束表示虚拟Dom已经挂载到真实元素上了,接下来我们就可以获取el了。我们可以使用console.dir来打印我们需要的一些元素的属性。至此,我们的挂载阶段就结束了。在更新阶段,让我们删除一个列表来查看更新状态。每当我们改变页面元素时,都会进入update阶段,也就是beforeUpdate和updated两种状态。销毁阶段让我们来看看最后的销毁阶段。beforeDestroy,销毁前的状态,销毁前,这样我们的元素和数据就可以像mount后的stage一样打印出来。destroyed,其实最让我震惊的是这个,销毁的状态是完成的,本以为销毁了应该什么都不打印出来,其实还是可以打印出所有东西的。beforeDestroy和destroyed是生命周期,只有当我们离开这个组件时才会调用。生命周期的各个阶段适合做什么先说说在不同的阶段我们可以做什么:Dom还没有挂载到真正的Dom上,所以此时我们无法访问我们的Dom元素(此时el属性和ref属性都是空的)。这个时候我们可以做一些简单的Ajax,可以初始化页面beforeMount:挂载前调用,此时会找到虚拟Dom,编译成Rendermounted:虚拟Dom已经挂载到真实Dom上了,现在我们可以拿到Dom节点,此时$ref也是可以访问的。这个时候我们可以获取节点信息,进行Ajax请求,对节点做一些操作此时访问现有的Dom。我们此时可以访问已有的Dom,手动移除一些添加的监听事件updated:此时打补丁,Dom已经更新,可以进行一些依赖于新Dom的操作。但是还是不建议此时进行数据操作,以免进入死循环(这个坑我踩过一次)beforeDestroy:在Vue实例销毁之前调用,此时我们的实例还没有销毁。这时候可以做一些操作,比如销毁定时器,解绑全局事件,销毁插件对象等等。子组件长什么样?我们只是做一个简单的加法。不知道大家有没有注意到刚才图片中的这两行:我们页面中的小li是嵌入在这个大页面中的一个子组件,我们还打印了它的生命周期:created(){console.log('listcreated')},mounted(){console.log('listmounted')},beforeUpdate(){console.log('listbeforeupdate')},updated(){console.log('listupdated')},beforeDestroy(){//及时销毁,否则可能造成内存泄漏console.log('listbeforeDestroy')},destroyed(){console.log('listDestroy')}复制代码并在这里获取,在父组件挂载之前,子组件已经挂载。不仅是挂载阶段,其他两个阶段我们也可以打印出来,这里就不细说了,直接总结:挂载阶段:父组件beforeMount->子组件创建->子组件挂载->父组件mountedupdate阶段:父组件beforeUpdate->子组件beforeUpdated->子组件updated->父组件updated销毁阶段:父组件beforeDestroy->子组件beforeDestroy->子组件销毁->父组件销毁在我们的请求所在的地方cycle会更合适至此我们对Vue的生命周期有了基本的了解,现在我们来说说我们的request应该放在哪个生命周期是最合适的。一般来说,答案有两种:创建和挂载。上面说了这两个答案,前者是数据准备好了,后者是连dom都加载好了,那么哪个才是正确答案呢?其实两者都可以,只是mounted会好一些。可能有人会说:创建的时间会早一些,早点调用会节省很多时间吗?这样性能会不会更高?别着急,让我们一点一点地看吧。首先,它确实早了,但并没有早几微秒,所以这实际上并没有提高性能。第二,我们没有在创建阶段做渲染。,所以接下来我们会做Dom渲染,但是如果这时候我们也做Ajax操作,Ajax结束后会返回数据,我们会插入到主线程中去运行处理数据,但是我们需要知道在浏览器机制中,渲染线程和js线程是互斥的,所以有可能我们在渲染的时候,对方可能要处理Ajax返回的数据,此时渲染可能会中断这次。处理数组后,重新渲染。如果创建了多个Ajax怎么办?我们又得重新渲染,那么在created中进行Ajax请求显然是不合适的。还有,有时候我们在接收到返回的数据的时候,可能需要在回调函数中进行一些Dom的操作,但是我们在created阶段还没有加载真正的Dom,所以相对来说还是在mounted中调用比较好有些如果是服务端渲染,我们会把它放到created里,因为服务端不支持mounted。最后,如果您觉得这篇文章对您有点帮助,请点个赞。或者可以加入我的开发交流群:1025263163互相学习,我们会有专业的技术解答。如果您觉得这篇文章对您有用,请给我们的开源项目一个小星星:https://gitee。com/ZhongBangKe...非常感谢!
