谈谈你对vue的生命周期的理解
vue整个生命周期实现了如下内容
initMixin(Vue) stateMixin(Vue) // 实现$watch $set $delete eventsMixin(Vue) // 实现$on $once $off $emit lifecycleMixin(Vue) renderMixin(Vue)
vue首先执行_init,此方法在 initMixin中
// 源码部分 initLifecycle(vm) initEvents(vm) // 事件监听器初始化 initRender(vm) callHook(vm, 'beforeCreate') initInjections(vm) // resolve injections before data/props initState(vm) // 初始化组件的各种状态 initProvide(vm) // resolve provide after data/props callHook(vm, 'created')
我们首先需要创建一个vue实例,也就是在 new Vue() 的对象过程中,首先执行了init(init是vue组件里面默认去执行的),在init的过程当中
1、首先初始化了生命周期(初始化一些vue实例上的参数)
2、初始化事件监听器(如:$on $off)
3、初始化render函数(模板渲染函数)
4、调用beforeCreate钩子函数
5、初始化 inject 函数
6、initState,初始化组件的各种状态(重要,响应式就在这里进行处理)
7、初始化 provide 函数
8、调用created钩子函数
通过上述得知,initState是在beforeCreate 钩子之后、在created钩子之前初始化的,所以我们最早可以在created钩子里面对数据进行操作。
在created之后会判断实例vm选项中是否有挂载el模板 vm.$options.el
如果有的话,执行$mount
$mount的作用是将挂载在vm实例上的el转化为render函数
在$mount中,先判断挂载的el是否是render,如果是,则直接下一步,如果不是,则判断是否有template这个选项,如果没有,则说明挂载了一个html节点,如果有,则对template进行转化处理
也就是说优先级为:render > template > 节点 最终都会解析成为一个render函数
render (h){ // h => createElement 的缩写 return h('div', {}, this.text) }
render函数是发生在beforeMount和mounted之间的,这说明了 在beforeMount的时候,$el还只是我们在HTML里面写的节点,然后到mounted的时候,它才把渲染出来的内容挂载到了DOM节点上。
在mounted挂载完毕后,这个实例就算是走完流程了。
后续的钩子函数执行的过程都是需要外部条件的触发才会执行。
比如有数据的变化,会调用beforeUpdate,然后经过Virtual DOM,最后updated更新完毕。
当组件被销毁的时候,它会调用beforeDestory,以及destoryed