vuejs源码解剖 — 从Vue构造函数入口开始

1,183 阅读1分钟

从Vue构造函数入口开始

我们知道Vue往往是从new开始工作的,这就说明Vue一定是个构造函数,那么它的原型链上肯定会暴露很多方法或者属性。鉴于Vue的规则,在看源码之前先大胆猜测一下,以下写法或者类似写法,应该会非常多:

Vue.prototype.$method = function(){
	//忽略
}
Vue.prototype._method = function(){
	//忽略
}

只是具体怎么实现的,或者说Vue的神秘之处有哪些,看完之后会不会拍大腿,我们带着这个疑问一探究竟。从入口位置顺藤摸瓜:core/instance/index.js

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'

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)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

我们看到一开始页面引入了五大Mixin方法,执行的时候唯一的参数就是Vue构造函数本身。主要是在不同阶段给Vue原型链上添加了不同的方法,本篇会先简单介绍这五大方法分别暴露了哪些方法或者属性,后面会有详细文章介绍。先来看下构造函数本身:

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)
}

构造函数主要做两件事:

  • 在非生产环境检测调用Vue是否是new出来的,如若不是则会打印一个警告;
  • 将你的options配置传入,执行Vue原型链上的内部方法_init

initMixin

主要做了哪些事情:

  • 合并配置
  • 初始化组件实例关系以及内部属性:比如当前组件的父组件(parent)、根组件(parent)、根组件(root)、子组件数组(children)容器、children)容器、refs以及内部属性等。
  • 初始化自定义事件
  • 初始化组件插槽信息
  • 调用生命周期函数beforeCreate
  • 初始化组件的 inject 配置项
  • 初始化状态。分别初始化 propsmethodsdatacomputedwatch(划重点!!!)
  • 初始化组件的 provide 配置项
  • 调用生命周期函数create
  • 如果是根组件(自定义配置上有el选项)则调用$mount自动挂载

stateMixin

构造函数Vue原型链上初始化$data$props属性,初始化$set$delete$watch方法

eventsMixin

构造函数Vue原型链上初始化$on$once$off$emit方法

lifecycleMixin

构造函数Vue原型链上初始化_update$forceUpdate$destroy方法

renderMixin

构造函数Vue原型链上初始化$nextTick_render方法

总结

Vue将主逻辑分别封装在不同的Mixin方法中初始化,写的非常清楚,更方便了定位分析,非常值得我们学习借鉴。
本篇只梳理了Vue初始化主要做了哪些事情的结构,顺着这个主心骨,接下来再一一详细解剖。