vue-cli和vue的区别_vue的生命周期_猪周期 几年一个周期

每个前端框架都有自己的优势和特点,真的没有一个标准可以判断哪个框架更好一点,只能说哪个框架更适合你要做的业务。希望 FEer 们不要为了哪个框架更牛逼再起硝烟,我们期盼世界和平。

2014 年 2 月,尤雨溪先生(Evan You)开源了一个前端开发库 Vue.js 。从 1.0 版本到 2.0 版本 ,Vue 在轻量和功能之间找到更佳科学的平衡点,不仅性能上得到极大的提升,同时也拓展了更多的使用场景。 Vue 的核心思想就是:数据驱动的组件系统,而组件的本质就是一个拥有预定义选项的 Vue 实例。在实例化 Vue 的过程中,需要传入一个包含数据、模板、挂载元素、方法、生命周期钩子等的选项对象,这篇文章将用通俗易懂的语言让 Vue 初学者全面了解 Vue 生命周期钩子。

初识 Vue 生命周期钩子

每个 Vue 实例在被创建之前都要经过一系列的初始化过程。在这个过程中, Vue 实例会调用一些生命周期钩子,给开发者提供执行自定义逻辑的机会。在Vue 2.0中,生命周期钩子相比之前的版本发生了很大的变化。下面先看一张图,这是Vue 官方文档中关于 Vue 生命周期的解释图。

vue-cli和vue的区别_vue的生命周期_猪周期 几年一个周期

相信很多初学者看到这张图都会一脸懵逼,从内心里发出“ What are you 弄啥嘞? ”的咆哮。现在不懂没关系,如果你对 Vue 实例拥有一定了解,可以接着往下看。如果你对 Vue 实例了解不多,建议对 Vue 官方文档中“ Vue 实例”小节进行系统学习。如果看完这篇文章后,你还不懂 Vue 生命周期钩子vue的生命周期,那就一定是我的锅!

每个钩子都有自己的职责

就像我们人这一辈子,幼年玩土,少年读书,青年加班,中年得子,晚年跳跳广场舞,每个 Vue 实例从创建到销毁也要经历不同的阶段,每个钩子也只做特定的事情。就像雇佣童工是非法的,在beforeCreate钩子中调用data对象中的属性也不行。下面,我们结合具体代码去理解钩子的执行。

在chrome浏览器的控制台里,只输出4个钩子的执行结果:

vue-cli和vue的区别_vue的生命周期_猪周期 几年一个周期

① beforecreated 钩子会在 Vue 实例初始化之后,数据观测和 event / watcher 事件配置之前被调用。在控制台中可以看到 el 和 data 并未初始化。② created 钩子会在 Vue 实例创建完成之后被调用。在控制台中可以看到 data 已经初始化,但是 el 却依然没有初始化。③ beforeMount 钩子会在模版编译之后执行,在此期间 Vue 实例挂载还未开始,相关的 render 函数首次被调用。在控制台中可以看到 data 和 el 都已经初始化,此时 message 的值还没有渲染。④ mounted 钩子会在 el 被新创建的 vm.$el 替换,并且 Vue 实例挂载之后被调用。在控制台中可以看到

标签的内容已经发生变化,此时模板中的HTML在Web页面中渲染。

接下来,我们在控制台再执行一些代码,触发剩下的钩子陆续执行。

app.message= '用科技让复杂的世界更简单';

vue的生命周期_vue-cli和vue的区别_猪周期 几年一个周期

可以看到当我们修改 data 对象的属性值时,会相继触发 beforeUpdate 钩子和 updated 钩子的执行。数据更新会引发 Virtual DOM 重新渲染和打补丁,这便是 beforeUpdate 钩子和 updated 钩子的分界线。

app.$destroy();

vue-cli和vue的区别_猪周期 几年一个周期_vue的生命周期

关于销毁,会依次触发 beforeDestroy 钩子和 destroyed 钩子。实例销毁之前,在 beforeDestroy 钩子里 Vue 实例依然完全可用。Vue 实例销毁之后,在 destroyed 钩子里 Vue 实例指示的所有东西都会解绑vue的生命周期,所有的事件监听器都会被移除,所有的子实例也会被销毁。

Vue 实例销毁后,再修改 message 的值,你会有惊喜的发现。虽然数据变了,但是并没有驱动视图进行更新。

猪周期 几年一个周期_vue-cli和vue的区别_vue的生命周期

最后,还有2个成对出现的钩子没有向大家介绍,那就是activated 钩子和 deactivated 钩子。所以,我们要再来一波代码。如果有对 vue-router 不熟悉的同学,需要先行了解这个构建 Vue 单页面应用的神器,这样可以更好的理解组件缓存机制。

在 Vue 的设计中, 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。当组件在 内被切换,它的 activated 钩子和 deactivated 钩子会被对应执行。下面,我们开始实验:先从 FE 小哥哥切换到 FE 小姐姐,然后再切换回 FE 小哥哥。

我们继续看控制台:Boy 组件和 Girl 组件只有在第一次渲染时,created 、mounted 和 activated 这3个钩子全部被调用,后面再进行组件切换时就只有activated 钩子和 deactivated 钩子分别执行。

转变操作DOM的思维

现在思考一个问题:如果在某个钩子中修改了数据,而DOM元素还没有来得及渲染,我们如何获取这个DOM元素?

思考30s …

要不要再给你一点时间?

首先,这个问题本身就有问题。Vue 的中心思想是用数据驱动视图的变化,这就需要我们转变利用原生 JavaScript 或者 Jquery 开发时操作DOM元素的惯性思维。如果业务中真的出现这样的需求,必须先思考是不是代码设计上出现不妥,或者思考能否在其他钩子中进行相关逻辑的操作?不过凡事都有例外,如果你真的要手动操作DOM元素,Vue 还是提供的一个 API ,就是 Vue.nextTick 。现在我们对上面提到的第一波代码进行一点小小的改造,在 beforeCreate 钩子中再加入这个 API 的调用。

vue的生命周期_猪周期 几年一个周期_vue-cli和vue的区别

vue的生命周期_vue-cli和vue的区别_猪周期 几年一个周期

运行代码之后,我们再次观察控制台。正常情况下,在 beforeCreate 钩子中 el 和 data 都应该是undefined,这会导致我们无法修改 message 的值。Vue.nextTick 可以做到在下次 DOM 元素更新循环结束之后执行延迟回调。修改数据之后立即使用这个方法,可以获取更新后的 DOM 元素,就巧妙地解决了这个尴尬的问题。

西二旗,不相信眼泪

讲了这么多,就是希望每个初学者都可以在 Vue 生命周期中的不同时机,选择合适的钩子执行相关业务逻辑的操作。比如:可以在 beforecreate 钩子中添加 loading 效果和其它等待动画。在 created 钩子中而不是mounted 钩子中开始请求 server 接口数据,或者执行一些初始化操作。在 destoryed 钩子中回滚某些操作,或者清空相关的数据设置。合理地使用框架确实可以达到事半功倍的效果,同时也建议各位同学不要过分依赖框架。毕竟熟练地使用各种框架只能让你沦为一个完成需求的流水工,而深入了解框架的实现原理、夯实 JavaScript 编程基础才能让你成长为一个既懂得用轮子也可以造轮子的前端 Coder 。