vue生命周期详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue生命周期详解相关的知识,希望对你有一定的参考价值。
参考技术Avue源码中最终执行生命周期函数都是调用 callHook 方法, callHook 函数的逻辑很简单,根据传入的生命周期类型 hook ,去拿到 vm.$options[hook] 对应的回调函数数组,然后遍历执行,执行的时候把 vm 作为函数执行的上下文。
1. new Vue(options) :创建一个vm实例;
2. mergeOptions(resolveConstructorOptions(vm.constructor), options, vm) :合并Vue构造函数里options和传入的options或合并父子的options。比如:在mergeOptions函数中会调用mergeHook方法合并生命周期的钩子函数,mergeHook方法原理是只有父时返回父,只有子时返回数组类型的子。父、子都存在时,将子添加在父的后面返回组合而成的数组。这也是父子均有钩子函数的时候,先执行父的后执行子的的原因;
3. initLifecycle(vm)、initEvents(vm)、initRender(vm) :在创建的vm实例上初始化生命周期、事件、渲染相关的属性;
4. callHook(vm, \'beforeCreate\') :调用beforeCreate生命周期钩子函数;
5. initInjections(vm)、initState(vm)、initProvide(vm) :初始化数据:inject、state、provide。initState 的作用是初始化 props、data、methods、watch、computed 等属性;
6. callHook(vm, \'created\') :调用created生命周期钩子函数;
7. vm.$mount(vm.$options.el) : $mount 方法在多个文件中都有定义,如"src/platform/web/entry-runtime-with-compiler.js"、"src/platform/web/runtime/index.js"、"src/platform/weex/runtime/index.js"。因为 $mount 方法的实现是和平台、构建方式相关的。以"entry-runtime-with-compiler.js"为例,关键步骤是查看 vm.$options 中是否有render方法,如果没有则会根据el和template属性确定最终的template字符串,再调用 compileToFunctions 方法将template字符串转为render方法,最后,调用原先原型上的$mount方法,即开始执行"lifecycle.js"中 mountComponent 方法;
8. callHook(vm, \'beforeMount\') :调用beforeMount生命周期钩子函数;
9. vm._render() => vm._update() => vm.__patch__() :先执行vm._render方法,即调用createElement生成虚拟DOM,即VNode ,每个VNode有children ,children 每个元素也是⼀个 VNode,这样就形成了⼀个 VNode Tree;再调用vm._update方法进行首次渲染,vm._update方法核心是调用vm. patch 方法,这个方法跟vm.$mount一样跟平台相关;vm. patch 方法则是根据生成的VNode Tree递归createElm方法创建真实Dom Tree挂载到Dom上;
10. callHook(vm, \'mount\') :调用mount生命周期钩子函数:VNode patch 到 Dom 之后会执行 \'invokeInsertHook\'函数,把 insertedVnodeQueue 中保存的mount钩子函数执行一遍,insertedVnodeQueue队列中的钩子函数是在根据VNode Tree递归createElm方法创建真实Dom Tree过程生成的钩子函数顺序队列,因此mounted钩子函数的执行顺序是先子后父;
11. data changes :数据更新,nextTick中执行 flushSchedulerQueue 方法,该方法会执行watcher队列中的watcher;
12. callHook(vm, \'beforeUpdate\') :执行watcher时会执行watcher的before方法,即调用beforeUpdate生命周期钩子函数;
13. Virtual DOM re-render and patch :重新render生成新的Virtual DOM,并且patch到DOM上;
14. callHook(vm, \'updated\') :调用updated生命周期钩子函数;
15. vm.$destroy() :启动卸销毁过程;
16. callHook(vm, \'beforeDestroy\') :调用beforeDestroy生命周期钩子函数;
17. Teardown watchers, childcomponents and event listeners :执行一系列销毁动作,在 $destroy 的执行过程中,它又会执行 vm.__patch__(vm._vnode, null) 触发它子组件的销毁钩子函数,这样一层层的递归调用,所以 destroyed 钩子函数执行顺序是先子后父,和 mounted 过程一样。
18. callHook(vm, \'destroyed \') :调用destroyed 生命周期钩子函数。
Vue生命周期函数详解解读
参考技术A // 这里是创建阶段的生命周期beforeCreate()
// 第一个生命周期函数,表示实例完全被创建出来之前,会执行它
,
created()
// 第二个生命周期函数
,
beforeMount()
// 第三个生命周期函数,表示 模板已经在内存中编辑完成了,但是尚未把模板渲染到页面中
// 在beforeMount执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串
,
mounted()
// 第四个生命周期函数,表示,内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
// 实例创建期间的最后一个生命周期函数,当执行完mounted就表示,实例而已经被完全创建好了,此时,如果没有其它操作的话,这个实例就静静的躺在我们的内存中,一动不动
// 如果要通过某些插件操作页面上的dom节点,最早要在mounted中进行
// 只要执行完了mounted,就表示整个vue实例已经初始化完毕了,此时组件脱离了创建阶段,进入到运行阶段
,
// 这里是运行阶段的生命周期函数
// 会根据data数据的改变,有选择性的触发0次到多次
beforeUpdate()
// 这时候表示我们的界面还没有被更新 【数据更新了】
// 当执行beforeUpdate的时候,页面中的显示的数据,还是旧的,此时data数据是最新的,页面尚未和最新的数据保持同步
,
updated()
// updated 事件执行的时候,页面和data数据已经保持同步了,都是最新的
,
beforeDestroy()
// 当执行beforeDestroy钩子函数的时候,vue实例就已经从运行阶段,进入到了销毁阶段
// 当执行beforeDestroy的时候,实例身上所有的打他和所有的methods,以及过滤器..指令..... 都处于可用状态,此时,还没有真正执行销毁的过程
,
destroyed()
// 当执行到destroyed函数的时候,组件已经被完全销毁了,此时,组件中所有的数据、方法、指令、过滤器...都已经不可用了
以上是关于vue生命周期详解的主要内容,如果未能解决你的问题,请参考以下文章