Vue生命周期初探
本来想从这就开始写关于vue的模板语法的,但是思前想后,觉得还是应该先学习一下vue的完整生命周期,随便写一下,想到哪儿就写到哪儿。
先写一下页面显示的几个阶段。
1.生成DOM树(包括display:none的节点)。
2.在DOM树的基础上根据节点的属性生成Render树(不包括display:none,head节点,包括visibilty:hidden的节点)
3.在render树的基础上继续渲染颜色,背景色等样式。
每个 Vue 实例在被创建时都要经过一系列的初始化过程。
这个完整的生命周期图片太长了,我们从每一个钩子截图看一下。
1.beforeCreate

实例或组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载,无法访问到数据和真实的dom,我们一般不会在此处进行任何操作。
2.created

在执行完成beforeCreate之后,vue会进行初始化事件,进行数据的观测,在这时数据已经和data的属性绑定了,你改变data的属性,同时视图也会随着更新。我们一般在这个钩子里获取数据进行初始化。
这时还没有$el
3.beforeMount

这个阶段发生了很多事情。
首先会判断对象是否有el选项。如果有的话就继续向下编译,如果没有el选项,则停止编译,也就意味着停止了生命周期,直到在该vue实例上调用vm.$mount(el)才继续向下走。
在这个函数中虚拟Dom已经创建完成,马上开始render()
为什么先判断el然后判断template?
vue需要通过el找到对应的outer template
渲染的优先级如下:
render函数选项 > template选项 > outer HTML.
4.mounted

在mounted之前,template模板中还是通过{{data}}进行占位的,因为此时还没有挂在真实dom上,还是以JS中的虚拟dom存在的。
接下来开始render(),渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom。
4. beforeUpdate &updated

当vue发现data中的数据发生了改变,会触发对应组件的重新渲染,先后调用beforeUpdate和updated钩子函数。
vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染。
当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom。
4.
beforeDestroy
&
destroyed

beforeDestroy钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。我们在这一步一般进行一些清除定时器一类的操作。
destroyed钩子函数在Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。