码迷,mamicode.com
首页 > 其他好文 > 详细

vue生命周期详解

时间:2020-04-15 15:13:18      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:bst   构造函数   live   保存   开始   继承   图片   origin   ntc   

1.vue基本生命周期

 
技术图片

vue源码中最终执行生命周期函数都是调用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):初始化数据:injectstateprovide。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 生命周期钩子函数。

2. errorCaptured生命周期钩子函数

  • 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

  • 如果一个组件的继承或父级从属链路中存在多个 errorCaptured 钩子,则它们将会被相同的错误逐个唤起。

  • 默认情况下,如果全局的 config.errorHandler 被定义,所有的错误仍会发送它,因此这些错误仍然会向单一的分析服务的地方进行汇报。

3. keep-alive组件

  • keep-alive组件是vue的内置抽象(abstract)组件,抽象组件在initLifecycle过程中 组件实例建立父子关系时会被忽略,因此他自身不会渲染一个DOM元素,也不会出现在父组件链中。

  • keep-alive作用是用于包裹动态组件,缓存不活动的组件实例。keep-alive自定义实现了render函数并利用了插槽slot,render函数中先获取它的默认插槽,再获取到它的第一个组件子节点,因此keep-alive组件只处理第一个子元素,所以一般和它搭配使用的有component动态组件或者router-view。

  • keep-alive组件在created钩子中定义了 this.cache 和 this.keys,本质上是去缓存已创建的 vnode,缓存策略采用LRU策略,每次缓存命中时将当前vnode移到缓存数组末尾,需要删除时则删除缓存数组第一个vnode。

  • keep-alive组件接收三个props:

    1. include:数组、字符串或者正则表达式,只有匹配的组件才会缓存。

    2. exclude:数组、字符串或者正则表达式,任何匹配的组件都不会被缓存。

    3. max:字符串或数字,指定可以缓存的组件最大个数,如果个数超过max,则销毁缓存数组中的第一个组件。

  • keep-alive组件子组件渲染机制:

    1. 首次渲染:和普通组件一样执行正常的init生命周期钩子函数,同时将生成的vnode缓存到内存中;

    2. 组件切换:切换到新组件时,旧组件不会销毁,而是变成未激活状态,即不会执行destroy相关的钩子函数,而是执行 deactivated 生命周期钩子函数,如果新组件不在缓存数组中,则执行首次渲染,否则执行缓存渲染;

    3. 缓存渲染:缓存渲染即组件由未激活状态变成激活状态,因此不会执行created、mounted等钩子函数,而是执行 activated 生命周期钩子函数。


原文链接:https://www.jianshu.com/p/af493b7dd4e8

vue生命周期详解

标签:bst   构造函数   live   保存   开始   继承   图片   origin   ntc   

原文地址:https://www.cnblogs.com/shuaigebie/p/12705415.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!