Vue 源码-运行时入口

125 阅读1分钟

vue版本:v2.7.10

入口

src/platforms/web/runtime/index.ts

import Vue from 'core/index' // 指向src/core/index.ts 
import config from 'core/config'
import { extend, noop } from 'shared/util'
import { mountComponent } from 'core/instance/lifecycle'
import { devtools, inBrowser } from 'core/util/index'
...
import { patch } from './patch'
import platformDirectives from './directives/index'
import platformComponents from './components/index'
import type { Component } from 'types/component'
// 添加内置指令(v-model、v-show)和内置组件(Transition、TransitionGroup)
extend(Vue.options.directives, platformDirectives)
extend(Vue.options.components, platformComponents)
// 添加patch函数,包含diff算法
Vue.prototype.__patch__ = inBrowser ? patch : noop
// 添加挂载函数
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}
// 检测devtools并输出信息
if (inBrowser) {
...
}
export default Vue

Vue最核心的功能实现在src/core/index.ts,此文件中额外添加了一些内置指令和组件,添加了__patch__实现diff算法,并实现了$mount函数用于挂载vue实例在dom元素上。

src/core/index.ts

import Vue from './instance/index' //指向src/core/instance/index.ts
import { initGlobalAPI } from './global-api/index'
import { isServerRendering } from 'core/util/env'
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
// 为Vue扩展构造器属性,用于全局调用,包括
// Vue.util、Vue.set、Vue.delete、Vue.nextTick
// Vue.use、Vue.mixin、Vue.extend、Vue.component、Vue.directive、Vue.filter等
initGlobalAPI(Vue)

/** 服务端渲染相关 **/
Object.defineProperty(Vue.prototype, '$isServer', {
  get: isServerRendering
})
Object.defineProperty(Vue.prototype, '$ssrContext', {
  get() {
    return this.$vnode && this.$vnode.ssrContext
  }
})
Object.defineProperty(Vue, 'FunctionalRenderContext', {
  value: FunctionalRenderContext
})
/******/

export default Vue

Vue构造函数的实现在src/core/instance/index.ts,此文件中还为Vue构造函数添加了一些全局调用的函数。

src/core/instance/index.ts

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'
import type { GlobalAPI } from 'types/global-api'

function Vue(options) {
  if (__DEV__ && !(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 as unknown as GlobalAPI

终于看到Vue的构造函数了,传入的options参数透传给内部的_init函数调用。 导入的多个mixin函数为了Vue原型添加函数和属性:

  • initMixin添加了_init函数
  • stateMixin添加了$data$props属性和$set$delete$watch函数
  • eventsMixin添加了$on$off$emit$once函数,为Vue内置了事件监听机制
  • lifecycleMixin添加了内部调用的_update函数和供外部调用的$forceUpdate$destroy函数
  • renderMixin添加一些系列Vue内部工具函数,还有_render用于实现渲染功能,$nextTick供外部使用

接下去我们通过initMixin函数继续往下探索