vue生命周期的理解
前几天面试,被面试官问对vue生命周期的理解,发现会使用,但这完全还不行,对vue生命周期理解还不到位,正好索性看些资料再理解理解;
vue生命周期图
在调用beforeCreate()函数时,只进行了一些必要的初始化操作(例如一些全局的配置和根实例的一些属性初始化),此时data属性为undefined,没有可供操作的数据。
调用Created()函数,在这一步,实例已完成以下的配置:数据代理和动态数据绑定(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
在调用boforeMount()
函数前首先会判断对象是否有el选项。
- 如果有的话就继续向下编译;
- 如果没有el选项,则停止编译,也就意味着停止了生命周期,直到在该vue实例上调用vm.$mount(el) ;
在这个例子中,存在有el元素,因此会调用boforeMount()函数,此时已经开始执行模板解析函数,但还没有将$el元素挂载页面,页面视图因此也未更新。
在标红处,还是 {{message}},这里就是应用的Virtual DOM(虚拟Dom)技术,先把位置占住。到后面mounted挂载的时候再把值渲染进去。
在父组件执行beforeMount阶段后,进入子组件的beforeCreate、Created、beforeMount阶段,这些阶段和父组件类似。子组件的beforeMount 阶段后,执行的是子组件的Mounted 阶段,该阶段时子组件已经挂载到父组件上,并且父组件随之挂载到页面中。
由此可以知道,在beforeMount阶段之后、Mounted阶段之前,数据已经被加载到视图上了,即$el元素被挂载到页面时触发了视图的更新。
mounted执行时:此时el已经渲染完成并挂载到实例上。
至此,从Vue实例的初始化到将新的模板挂载到页面上的阶段已经完成,退出debugger。
父子组件生命周期执行顺序
注意点
1、created钩子函数和beforeMount间的生命周期,首先系统会判断对象中有没有el选项
- 有el选项,则继续编译过程;
- 没有el选项,则停止编译,也意味着暂时停止了生命周期,直到vm.$mount(el),手动执行vm. $ mount(el)方法的话,也能够使暂停的生命周期进行下去;
2、template参数选项的有无对生命周期的影响
- 如果Vue实例对象中有template参数选项,则将其作为模板编译成render函数;
- 如果没有template参数选项,则将外部的HTML作为模板编译(template),也就是说,template参数选项的优先级要比外部的HTML高;
- 如果1,2条件都不具备,则报错;
3、为什么判断el要发生在判断template前面呢
因为Vue需要通过el的“选择器”找到对应的template。总结一下这个过程,Vue通过el参数去找到对应的template。然后,根据el参数给出的“选择器”,首先去Vue实例对象本身的template选项参数中找,如果没有template参数,则到外部HTML中寻找,找到后将模板编译成render函数;
【注意】 render选项参数比template更接近Vue解析器!所以综合排列如下:
render函数选项 > template参数 > 外部HTML
4、Vue的编译过程——把模板编译成 render 函数
Vue的编译实际上是指Vue把模板编译成 render 函数的过程
5、beforeUpdate钩子函数和updated钩子函数间的生命周期
在Vue中,数据更改会导致虚拟 DOM 重新渲染,并先后调用beforeUpdate钩子函数和updated钩子函数;
重渲染(调用这两个钩子函数)的前提是被更改的数据已经被写入模板 template 中!!
只有Vue实例中的数据被“写入”到我们的模板 template 中,它的改变才可以被Vue追踪,重渲染从而调用 beforeUpdate钩子函数和updated钩子函数
6、beforeDestroy和destroyed钩子函数间的生命周期
beforeDestroy钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed钩子函数在Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
7、created函数
created钩子可以获取Vue的data,调用Vue方法,获取原本HTML上的直接加载出来的DOM,但是无法获取到通过挂载模板生成的DOM(例如:v-for循环遍历Vue.list生成li)
主要应用:调用数据,调用方法,调用异步函数;
8、补充$mount
当vue没有挂在el时,我们可以用$mount
var app = new Vue({
data: { message: 'this is mseeage' }
}).$mount('#app')
9、render函数
render函数是什么?
简单的说,在vue中我们使用模板HTML语法组建页面的,使用render函数我们可以用js语言来构建DOM
因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程。
当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具。官网上给他起了个名字叫createElement。还有约定的简写叫 h,
vm中有一个方法 _c,也是这个函数的别名;
说明: render是一个方法,自带一个形参createElement,这个参数也是一个方法,是用来创建vue 节点的,也就是html模板的,然后渲染 (render) 到指定的节点上;
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
写法如下:
render: function (createElement) {
return createElement(App);
}
// 缩写:
render (createElement) {
return createElement(App);
}
// 缩写:
render (h){
return h(App);
}
// 缩写:
render: h => h(App);