入口文件
完整版的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)
}