import vue经历了哪些完成初始化过程
1-5提到的Vue.js
源码构建过程在web
应用下,分析的是Runtime+Compiler
构建出来的Vue.js
,它的入口是src/platforms/web/entry-runtime-with-compiler.js
1、entry-runtime-with-compiler.js文件解析
最终导出的是vue
对象
export default Vue
vue
是通过import
导入
import Vue from './runtime/index'
然后挂载了一个$mount
方法
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (
//.......
)
2、runtime/index.js文件解析
最后也是导出vue
export default Vue
vue
是从core/index
引入
import Vue from 'core/index'
定义vue
的静态的全局配置
// install platform specific utils
Vue.config.mustUseProp = mustUseProp
Vue.config.isReservedTag = isReservedTag
Vue.config.isReservedAttr = isReservedAttr
Vue.config.getTagNamespace = getTagNamespace
Vue.config.isUnknownElement = isUnknownElement
定义原型的patch
和$mount
方法
// install platform patch function
Vue.prototype.__patch__ = inBrowser ? patch : noop
// public mount method
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
3、core/index.js文件解析
最后也是导出vue
export default Vue
vue
是从instance/index
引入
import Vue from './instance/index'
初始化API
,也就是在vue
上挂载一些静态属性
import {
initGlobalAPI } from './global-api/index'
initGlobalAPI(Vue)
4、instance/index.js文件解析(主要)
找到了vue
的定义,在定义vue
必须要通过一个new
的方法去实例化,这是es5实现class
的一种方式
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)
}
问:为什么要通过function
实现vue
?
答:调用了很多mixin
的方法,initMixin
实际上就是往Vue.prototype
上挂了一个init
方法,其他也是类似,也就是说每一个mixin
就是往vue
的原型上混入一些定义在原型上的方法
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
问:为什么不用es6用es5?
答:es5可以往vue
的原型上挂很多方法,并且把这些方法按代码模块组织关系拆分到不同文件下,方便代码管理,es6比较难实现
总结:因此vue
实际上就是一个function
,是用函数实现的一个类,可以理解为vue
就是一个类,类上挂了很多原型的方法,除了mixin
混入的方法,前面./runtime/index
下也会往原型上挂方法,包括入口entry-runtime-with-compiler.js
也会挂一些方法,除了原型上的方法,还有全局方法global-api
,看5、global-api/index.js文件解析
5、global-api/index.js文件解析(挂载静态方法)
往vue
的config
上定义了configDef
,config
来源是../config
,定义了很多vue
的全局config
,具体可以看vue
官网的api
import config from '../config'
Object.defineProperty(Vue, 'config', configDef)
定义了vue
的util
方法,这个方法官网不建议外面的库去使用,因为里面的方法的实现可能不稳定
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
还提供了set
、delete
、nextTick
方法,options
实际上是可以合并一些方法,ASSET_TYPES
看6、shared/constants.js文件解析
import {
ASSET_TYPES } from 'shared/constants'
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
Vue.options = Object.create(null)
ASSET_TYPES.forEach(type => {
Vue.options[type + 's'] = Object.creat(null)
})
定义了base
指向vue
,builtInComponents
是内置组件,看7、components/index.js文件解析,keep-alive
通过extend
方法扩展到components
下
import builtInComponents from '../components/index'
Vue.options._base = Vue
extend(Vue.options.components, builtInComponents)
定义了一个全局Vue.use
、Vue.mixin
、Vue.extend
程序方法,总而言之在初始化过程中,完成了全局方法的定义,定义之后我们就可以在代码中进行使用
import {
initUse } from './use'
import {
initMixin } from './mixin'
import {
initExtend } from './extend'
import {
initAssetRegisters } from './assets'
//(挂载原型方法)
initUse(Vue)
initMixin(Vue)
initExtend(Vue)
initAssetRegisters(Vue)
6、shared/constants.js文件解析
ASSET_TYPES
是定义了全局的component
、directive
、filter
这些方法
export const SSR_ATTR = 'data-server-rendered'
export const ASSET_TYPES = [
'component',
'directive',
'filter'
]
7、components/index.js文件解析
导出了一个KeepAlive
,keep-alive
是内置组件,
import KeepAlive from './keep-alive'
export default {
KeepAlive
}