写文章不容易,点个赞呗兄弟
专一 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工做原理,源码版助于了解内部详情,让咱们一块儿学习吧
研究基于 Vue版本 【2.5.17】
若是你以为排版难看,请点击 下面连接 或者 拉到 下面关注公众号也能够吧node
好的!今天探索Vue的生命周期,鉴于生命周期这个东西很简单,因此直接写源码版了函数
简单到什么程度呢,就是直接执行你的 created 什么的,只是分在何时执行而已学习
可是!咱们仍然要分两个问题,理清思路方便记忆this
一、生命钩子怎么触发 二、生命钩子在何时触发
首先,我设置了下面的例子spa
那么 el 和 created 就是你传入 Vue 的自定义选项啦prototype
一、把全部同类钩子先合并成数组,而后存放在 vm.$options3d
这个点跟 mixins 有关,能够看这篇下对钩子的合并处理code
合并,主要是为了把全局设置的钩子和 组件自定义的钩子合并起来,就算你没有全局钩子,也要存在数组里面,好比 created 是下面
vm.$options={ created:[fn,fn,fn...] }
二、初始化设置一些标志位,代表是否已经完成某种钩子
function initLifecycle(vm) { vm._isMounted = false; vm._isDestroyed = false; vm._isBeingDestroyed = false; }
这个函数会在 beforeCreated 钩子触发前调用,在 Vue.prototype._init 中,下个问题源码有显示。其中的标志位何时设置呢,是在相应的钩子触发以后,具体看下面源码
3怎么执行钩子呢
没错,就是下面这个函数
function callHook(vm, hook) { // 是本身传入的 created 等回调 var handlers = vm.$options[hook]; if (handlers) { for (var i = 0,j = handlers.length; i < j; i++) { handlers[i].call(vm); } } }
那是怎么用呢?
好比触发 created 就会这么调用
callHook(vm,'created')
很简单4不4,直接拿到钩子,而后遍历执行,绑定上下文对象。
为何是数组?上面已经说过啦,一个实例经过mixins可能有不少个相同钩子,因此合并成的数组
要说讲解钩子在何时触发把,好像也没什么讲的,Vue文档都说清楚了,可是很显然,因此咱们直接以源码的形式给出来
下面就说了几个钩子,有几个感受不太经常使用,就不列出来了
function Vue(opt){ this._init(opt) } Vue.prototype._init(opt){ ... 合并选项 ... 设置初始值 ,事件 等数据 initLifecycle(vm) callHook(vm, 'beforeCreate'); ... 初始化选项等数据 callHook(vm, 'created'); ...获取挂载的DOM 父节点 callHook(vm, 'beforeMount'); ...解析模板成渲染函数,并执行渲染函数,生成DOM插入页面 vm._isMounted = true; callHook(vm, 'mounted'); } // 组件更新时会调用这个函数 Vue.prototype._update = function( vnode, hydrating ) { if (vm._isMounted) { callHook(vm, 'beforeUpdate'); } ...从新调用渲染函数,对比旧节点和新节点,获得最小差别,而后只更新这部分页面 callHook(vm, 'updated'); } // 节点被移除时会调用这个函数 Vue.prototype.$destroy = function() { callHook(vm, 'beforeDestroy'); vm._isBeingDestroyed = true; ...实例被消除,移除全部 watcher vm._isDestroyed = true; ...DOM被移除 callHook(vm, 'destroyed'); }