vue2 响应式原理 - 初始化 - Vue实例

109 阅读1分钟

初始化过程 - Vue实例

src\platforms\web\entry-runtime-with-compiler.js

修改vue原型的$mount方法

最后导出vue实例方法

entry-runtime-with-compiler.js vue 实例方法 由src\platforms\web\runtime\index.js 文件导入

import Vue from './runtime/index'

runtime\index.js文件

extend(Vue.options.directives, platformDirectives)extend方法注册指令 v-model v-show

extend(Vue.options.components, platformComponents)extend方法注册组件 Transition TransitionGroup

在原型上定义__patch__函数Vue.prototype.__patch__ = inBrowser ? patch : noop inBrowser判断是否为浏览器环境typeof window !== 'undefined'

patch函数功能把虚拟dom 转换成真实dom

原型上注册$mount方法

// public mount method
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}

最后导出vue实例

runtime\index.js vue 实例方法 由 src\core\index.js 文件导入

core\index.js 文件

initGlobalAPI(Vue)方法调用 给Vue挂载静态方法

export function initGlobalAPI (Vue: GlobalAPI) {
  // config
  const configDef = {}
  configDef.get = () => config
  if (process.env.NODE_ENV !== 'production') {
    configDef.set = () => {
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      )
    }
  }
  // 初始化Vue.config 对象
  Object.defineProperty(Vue, 'config', configDef)

  // exposed util methods.
  // NOTE: these are not considered part of the public API - avoid relying on
  // them unless you are aware of the risk.
  // 这些工具方法不视作全局api的一部分 除非已经意识到风险 否则不要去依赖他们
  Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }
  // 静态方法 set/del/nextTick
  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  // 2.6 explicit observable API
  让一个对象可相应
  Vue.observable = <T>(obj: T): T => {
    observe(obj)
    return obj
  }
  // 初始化 Vue.options方法 并给其拓展
  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
  })

  // this is used to identify the "base" constructor to extend all plain-object
  // components with in Weex's multi-instance scenarios.
  Vue.options._base = Vue
  
  // 设置 keep-alive 组件
  extend(Vue.options.components, builtInComponents)
  
  // 注册 Vue.use() 注册插件
  initUse(Vue)
  // 注册 Vue.mixin() 实现混入
  initMixin(Vue)
  // 注册 Vue.extend() 基于传入的options返回一个数组的构造函数
  initExtend(Vue)
  // 注册 Vue.directive() Vue.compontent() Vue.filter()
  initAssetRegisters(Vue)
}

增加服务的渲染相关内容

Object.defineProperty(Vue.prototype, '$isServer', {
  get: isServerRendering
})

Object.defineProperty(Vue.prototype, '$ssrContext', {
  get () {
    /* istanbul ignore next */
    return this.$vnode && this.$vnode.ssrContext
  }
})

// expose FunctionalRenderContext for ssr runtime helper installation
Object.defineProperty(Vue, 'FunctionalRenderContext', {
  value: FunctionalRenderContext
})

最后导出vue实例

core\index.js vue 实例方法 由 src\core\instance\index.js 文件导入

instance\index.js页面

Vue实例方法

// 此处不用class原因是为了方便后续给Vue实例混入实例成员
function Vue (options) {
  // 判断是否使用new关键词调用
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  // 调用_init()方法
  this._init(options)
}

// 注册 vm 的 _init() 方法 初始化 vm
initMixin(Vue)
// 注册 vm 的 $data/$prop/$set/$delete/$watch
stateMixin(Vue)
// 初始化事件相关方法 $on/$once/$off/$emit
eventsMixin(Vue)
// 初始化生命周期相关的混入方法 _updata/$forceUpdate/$destroy
lifecycleMixin(Vue)
// 混入 render $nextTick/_render
renderMixin(Vue)

export default Vue // 导出Vue

总结 四个导出 Vue 的模块

  • src/platforms/web/entry-runtime-with-compiler.js

    • web 平台相关的入口 
      
    • 重写了平台相关的 $mount() 方法 
      
    • 注册了 Vue.compile() 方法,传递一个 HTML 字符串返回 render 函数
      
  • src/platforms/web/runtime/index.js

    • web 平台相关
    • 注册和平台相关的全局指令:v-model、v-show
    • 注册和平台相关的全局组件: v-transition、v-transition-group
    • 全局方法:
      -    __patch__:把虚拟 DOM 转换成真实 DOM
    
      -    $mount:挂载方法   
    
  • src/core/index.js

    • 与平台无关
    • 设置了 Vue 的静态方法,initGlobalAPI(Vue)
  • src/core/instance/index.js

    • 与平台无关
    • 定义了构造函数,调用了 this._init(options) 方法
    • 给 Vue 中混入了常用的实例成员

未完 。。。