Vue源码学习(二)——生命周期
官网对生命周期给出了一个比较完成的流程图,如下所示:
从图中我们可以看到我们的Vue创建的过程要经过以下的钩子函数:
beforeCreate => created => beforeMount => mounted
=> beforeUpdate => updated
=> beforeDestroy => destroyed
那么我们就从源码的角度来看一看吧,当我们new Vue的时候,会执行_init函数
function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}
init函数如下
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
....
以下就是进行了生命周期
vm._self = vm
// 首先进行初始化生命周期的参数
initLifecycle(vm)
// 在初始化事件
initEvents(vm)
// 初始化render
initRender(vm)
// 开始调用beforeCreate钩子函数,和图中的流程图一样
callHook(vm, 'beforeCreate')
// 之后开始初始化变量等一些数据
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
// 开始调用created钩子函数
callHook(vm, 'created')
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
vm._name = formatComponentName(vm, false)
mark(endTag)
measure(`vue ${vm._name} init`, startTag, endTag)
}
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
}
以上init函数我们已经看到了beforeCreate和created,那么callHook是怎么调用的钩子函数呢?
export function callHook (vm: Component, hook: string) {
// #7573 disable dep collection when invoking lifecycle hooks
pushTarget()
// 从$options里拿到钩子函数
const handlers = vm.$options[hook]
if (handlers) {
for (let i = 0, j = handlers.length; i < j; i++) {
try {
// 然后再调用
handlers[i].call(vm)
} catch (e) {
handleError(e, vm, `${hook} hook`)
}
}
}
if (vm._hasHookEvent) {
vm.$emit('hook:' + hook)
}
popTarget()
}
这边就会有几个问题:
从vm.$options[hook]中取钩子函数,那个这个钩子函数是哪来来的? 为了拿到的钩子函数是个数组?我们平时使用不都是只是写个函数吗?
我们可以看到在$options是在下面_init中进行合并的
Vue.prototype._init = function(){
...
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
...
}
export const LIFECYCLE_HOOKS = [
'beforeCreate',
'created',
'beforeMount',
'mounted',
'beforeUpdate',
'updated',
'beforeDestroy',
'destroyed',
'activated',
'deactivated',
'errorCaptured'
]
我们可以看到钩子函数一开始就已经在vue内部已经定义好了,并且还有几个钩子函数不是实话化实例的使用执行的。而是对keep-alive组件配合使用的activated,deactivated。以及错误抛出钩子函数errorCaptured
然后再根据这些内部定义的钩子函数和传入的参数进行合并
那么为什么钩子函数是数组呢?这个其实很简单是因为vue内部也需要执行一些函数,顾把函数也放到钩子函数里。所以需要数组遍历。
所以这些所谓的钩子函数就是一个回调函数。
其余几个钩子函数也是在需要调用的时候使用callHook(vm, 'xxx')来执行
如果对您有帮助请点个赞,谢谢!
原文地址:https://segmentfault.com/a/1190000016906255
Vue源码学习(二)——生命周期的更多相关文章
- Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...
- vue 源码学习二 实例初始化和挂载过程
vue 入口 从vue的构建过程可以知道,web环境下,入口文件在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compil ...
- Vue源码学习(二)$mount() 后的做的事(1)
Vue实例初始化完成后,启动加载($mount)模块数据. (一)Vue$3.protype.$mount 标红的函数 compileToFunctions 过于复杂,主要是生 ...
- Vue源码学习三 ———— Vue构造函数包装
Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...
- 手牵手,从零学习Vue源码 系列二(变化侦测篇)
系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 陆续更新中... 预计八月中旬更新完毕. 1 概述 Vue最大的特点之一就是数据驱动视 ...
- Vue源码学习1——Vue构造函数
Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...
- Vue源码分析(二) : Vue实例挂载
Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...
- Dubbo源码学习(二)
@Adaptive注解 在上一篇ExtensionLoader的博客中记录了,有两种扩展点,一种是普通的扩展实现,另一种就是自适应的扩展点,即@Adaptive注解的实现类. @Documented ...
- 最新 Vue 源码学习笔记
最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...
- 【Vue源码学习】依赖收集
前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...
随机推荐
- B1299 [LLH邀请赛]巧克力棒 博弈论
这个题一看就是nim游戏的变形.每次先手取出巧克力就是新建一个nim,但假如先手取一个为0的而且无论后手怎么取剩下的都无法为零就行了.然后用dfs跑. 题干: Description TBL和X用巧克 ...
- 47. Ext.form.Field.prototype.msgTarget
转自:https://blog.csdn.net/a1542aa/article/details/24295791 ExtJS.form中msgTarget Ext表单提示方式:msgTarget:有 ...
- form表单点击后验证
function check(){ var customertype = document.getElementById("customertype"); //alert(cust ...
- kindeditor上传文件的使用
在线富文本编辑器kindeditor配置(.Net Framework 3.5) 下载地址:http://kindeditor.net/down.php 解压放在项目要目录下, 在Bin目录下添加 ...
- [Swift通天遁地]五、高级扩展-(4)快速生成Invert、Mix、Tint、Shade颜色及调整饱和度阶
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- 【知识总结】回文自动机(Palindrome_Automaton)
参考资料:Palindromic Tree--回文树[处理一类回文串问题的强力工具](请注意,其中似乎有一些错误) 回文自动机似乎和回文树是同一个东西qwq? 回文自动机(PAM)是一种处理回文串的工 ...
- flask中的蓝图(BluePrint)
蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? 比如说,你有一个客户管理系统,最开始的时候,只有一个查看 ...
- STMP服务器发送邮件,本地可以发送但是服务器一直发送不成功;
在官网上查看到信息 考虑到部分云服务商封禁了其内网对外 25 端口的访问, xxxxx 端口号: 2525 xxxxx 端口号: 587 然后,我换了一下端口号就行了,浪费了我三个小时时间,贼尴尬:
- css文本背景样式
文本样式 文本类 text-transform:uppercase: 全部变为大写 text-transform:lowercase: 全部变为小写 text-transform:capitalize ...
- 实现div毛玻璃背景
毛玻璃效果 ios里毛玻璃效果的使用非常多,本文介绍一个实现div毛玻璃背景的方法 CSS3 Filter CSS3的Filter主要用在图像的特效处理上,默认值为none,还有以下备选项: 1. ...