new Vue、创建vue组件时,执行生命周期;
Vue实例化方式:
vue-cli2-runtime-compiler版本:
new Vue({
el: '#app',
components: { App },//第一步,注册组件,完整{App:App}
template: '<App/>'//第二步,使用组件,因为是js文件所以没有在页面上使用`<App></App>`
})
//template与el关系:有template就会替换el;
//这里可以直接用:render: h => h(App)
vue-cli2-runtime-only版本(少了js文件中解析template的代码):
new Vue({
el: '#app',
render: h => h(App) /=> render函数,返回一个函数:h(App):这个函数执行返回的就是虚拟dom
})
/=这里的App与上边runtime-compiler版本的App一样,
因为vue文件都被vue-template-compiler解析成对象形式了。
/=只是only版本中vue-template-compiler只作用于vue文件,
js文件中的就不处理了,所以不能在这里使用:template: '<App/>'
vue-cli3版本:
new Vue({
render: h => h(App), /=内部执行,生产虚拟dom,这里App是组件文件的对象,所以vue中 h()的参数有两种;
}).$mount('#app') /= 虚拟dom挂载
Vue生命周期:
总结:
beforeCreate钩子
:初始化内部事件、生命周期后执行;
created钩子
:初始化vue原型,导入子组件的只是组件文件的对象形式(不是组件对象),(只加载未解析),实例化自身vue对象完成后执行;
beforeMount钩子
:解析模板生成render函数,激活子组件的创建,父向子传值(上一步子组件的ast抽象语法树已经来了)后执行;
(子组件开始执行生命周期,创建并挂载到父组件上);
(如果子组件是通过父组件传值,父组件是异步请求获取值,这个值有没有到决定子组件是否创建的话,在传值到之前父组件会按undefined解析这个子组件
继续执行下一个钩子,而值传过去后子组件才开始渲染)
mounted钩子
:结合子组件的虚拟dom和自身vue实例对象、自身render函数,形成最终虚拟dom,并挂载后执行;
beforeUpdate钩子
:
updated钩子
:
beforeDestory钩子
:
destroyed钩子
:
1、创建前后:
beforeCreate
:创建前钩子函数;初始化事件(events)和生命周期函数(lifecycle)后执行(要执行周期等钩子函数要先初始化好);
created
:创建后钩子函数;初始化Vue原型(injections),data、methods,给Vue构造函数的原型传好数据用于实例化对象,如果内部有import
子组件此时将子组件模板解析成普通对象形式,并导入,并没有执行use()将对象传入Vue.extend()模板构造器中
,所以还没开始创建子组件,这一步是实例化完成后执行;所以此处常用于发送请求,请求初始数据。
2、挂载前后:
beforeMount
:挂载前钩子函数;检查什么方式创建组件,编译需要使用的模板组件,没有外界template模板就以el自身挂载元素(index.html中的)为模板来解析(挂载后就是替换自身),通过解析知道使用了子组件,并且有父传子的值也会传过去,template模板->ast抽象语法树->render函数;
生成该组件带变量的render函数
后执行,此时只是解析了<template>
部分,触发子组件的use()方法,子组件开始创建
,还没有与实例关联,数据还是变量形式;如App.vue,
mounted
:挂载后钩子函数;等待子组件创建并挂载后,结合子组件的虚拟dom,再结合之前创建好的自身的vue实例(数据、方法等),将给render函数传变量值执行返回h(),h()自执行生成虚拟dom
,生产完整的虚拟dom,并找到要挂载到的dom位置,如:#app,并用编译好的虚拟dom替换它,替换完成后执行;
3、更新前后:
beforeUpdate
:更新前钩子函数;当vue实例中data数据发生变化时执行;此时数据是最新的,页面还没有更新;
updated
:更新后钩子函数;当改变后的data数据重新渲染到虚拟dom后执行;
4、销毁前后
beforeDestroy
:销毁前钩子函数;当组件销毁被触发时执行(常见于组件切换);
destroyed
:销毁后钩子函数;拆除视图方的观察者(数据与视图的桥梁、发布订阅模式的成员)、子组件和事件监听后执行。