Vue-初始化笔记

325 阅读1分钟

入口文件

完整版的Vue的入口是在src\platforms\web\entry-runtime-with-compiler.js
当页面引入时先从这个文件开始import所需要的文件
entry-runtime-with-compiler.js 文件中import Vue from './runtime/index'
runtime\index.js(src\platforms\web\runtime\index.js)文件import Vue from 'core/index'
core\index.js(src\core\index.js)文件中
import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'
instance\index.js(src\core\instance\index.js)中定义Vue的构造函数
function Vue (options) 开始时的文件是从instance\index.js开始的

文件作用

instance\index.js: 是定义Vue构造函数,给Vue实例注册实例成员
src\core\index.js: 调用initGlobalAPI
global-api\index.js: 是给Vue挂载静态成员、静态方法
web\runtime\index.js: 注册model、show、transition、transition-group、__patch__ 、$mount
web\entry-runtime-with-compiler.js: 将template转成render

开始流程 (只列举部分代码)

instance\index.js开始,定义Vue的构造函数

  function Vue (options) {
    // new Vue时就是执行这里
    // 调用 _init() 方法
    this._init(options)
  }

继续执行instance\index.js
initMixin:注册 vm 的 _init() 方法,初始化 vm
stateMixin:注册 vm 的 $data、$props、$set、$delete、$watch
eventsMixin:初始化事件相关方法 $on、$once、$off、$emit
lifecycleMixin:初始化生命周期相关的混入方法_update、$forceUpdate、$destroy
renderMixin:混入 render$nextTick、_render

global-api\index.js 注册静态方法

初始化 Vue.config 对象 Object.defineProperty(Vue, 'config', configDef) 静态方法 set/delete/nextTick

Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
Vue.observable

初始化 Vue.options 对象,并初始化components/directives/filters

Vue.options = Object.create(null)
// ASSET_TYPES = ['component', 'directive', 'filter']
ASSET_TYPES.forEach(type => {
  Vue.options[type + 's'] = Object.create(null)
})

设置 keep-alive 组件

extend(Vue.options.components, builtInComponents)

注册全局静态方法

// 注册 Vue.use() 用来注册插件
initUse(Vue)
// 注册 Vue.mixin() 实现混入
initMixin(Vue)
// 注册 Vue.extend() 基于传入的options返回一个组件的构造函数
initExtend(Vue)
// 注册 Vue.directive()、 Vue.component()、Vue.filter()
initAssetRegisters(Vue)

web\runtime\index.js web平台相关处理

注册model、show、transition、transition-group

// platformDirectives = { model, show }
extend(Vue.options.directives, platformDirectives)
// platformComponents = { Transition, TransitionGroup }
extend(Vue.options.components, platformComponents)

注册__patch__

Vue.prototype.__patch__ = inBrowser ? patch : noop

注册$mount

Vue.prototype.$mount = function(el, hydrating) {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}

entry-runtime-with-compiler.js 将template转换成render

先保留 Vue 实例的 $mount 方法 (web\runtime\index.js中注册的)

const mount = Vue.prototype.$mount

重新赋值$mount

Vue.prototype.$mount = function(el, hydrating) {
  // 获取 el 对象
  el = el && query(el)
  // 获取options
  const options = this.$options
  // 判断有没有options.render
  if (!options.render) {
  	// 没有就找template
    let template = options.template
    // 如果模板存在
    if (template) {
    	// 有options.template
        // 提取对应的节点文本内容
    } else if (el) {
      // 如果没有 template,获取el的 outerHTML 作为模板
      template = getOuterHTML(el)
    }
    // 先找template 没有 再用el代替
    if (template) {
   	  // options.template 或者 el 其中有一个
      // 把 template 转换成 render 函数
      const { render, staticRenderFns } = compileToFunctions(template)
      // options存起来
      options.render = render
      options.staticRenderFns = staticRenderFns
    }
  }
  // 调用 mount 方法,渲染 DOM
  return mount.call(this, el, hydrating)
}