总结
这部分就是介绍Vue构造函数有什么方法和属性。没什么意思,直接给总结。
src/core/instance/index.js初始化Vue的原型(Vue.prototype)src/core/index.js初始化Vue的全局方法和属性src/platforms/web/runtime/index.js初始化平台相关的配置,patch方法和$mountweb/entry-runtime-with-compiler.js重写$mount使其拥有编译的能力
浏览器打印原型
浏览器打印全局方法和属性
起源
找到Vue构造函数相关的文件(怎么找?不再赘述)如下:
- web/entry-runtime-with-compiler.js
- src/platforms/web/runtime/index.js
- src/core/index.js
- src/core/instance/index.js
通过层层引用,最终找到真正定义Vue的地方src/core/instance/index.js。其实Vue的构造函数核心就是调用_init方法。new Vue实际上就是执行_init方法。
function Vue (options) {
// 必须使用new关键字来生产Vue实例
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)
}
// 向Vue的原型上添加_init方法
initMixin(Vue)
// 向Vue的原型上添加 $set, $watch, $delete方法
// 并将_data和_props代理到实例上
stateMixin(Vue)
// 初始化事件模型, 发布订阅者模式
eventsMixin(Vue)
// 向vue原型上添加_update, $forceUpdate, $destory
lifecycleMixin(Vue)
// 向Vue原型上添加$nextTick,_render方法和一系列的render帮助函数
renderMixin(Vue)
src/core/instance/index.js中执行的方法,都是为Vue.prototype添加一些方法。其中就有常用的$set,$emit,$nextTick...
Vue.protoType = {
// initMixin
_init: function,
// stateMixin
$set: set,
$delete: del,
$watch: function,
$data: get(_data),
$prop: get(_props),
// eventsMixin
$on: function,
$once: function,
$off: function,
$emit: function,
// lifecyycleMixin
_update: function,
$forceUpdate: function,
$destory: function,
// renderMiXin
$nextTick: function,
_render: function,
// installRenderHelpers
// 帮助生成render函数的方法
_o: function,
_n: function,
_s: function,
_l: function,
_t: function,
_q: function,
_i: function,
_m: function,
_f: function,
_k: function,
_b: function,
_v: function,
_e: function,
_u: function,
_g: function,
_d: function,
_p : function,
}
之后,被src/core/index.js引用,并执initGlobalAPI,为Vue添加静态方法和初始化配置。
// 初始化全局方法
initGlobalAPI(Vue)
// 会被替换为package.json中的版本号
Vue.version = '__VERSION__'
// src/core/global-api/index.js
export function initGlobalAPI (Vue: GlobalAPI) {
// config
const configDef = {}
configDef.get = () => config
// 定义config属性
Object.defineProperty(Vue, 'config', configDef)
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
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 = Object.create(null)
ASSET_TYPES.forEach(type => {
Vue.options[type + 's'] = Object.create(null)
})
Vue.options._base = Vue
// 添加内置组件keep-alive
extend(Vue.options.components, builtInComponents)
// 初始化use方法
initUse(Vue)
// 初始化mixin
initMixin(Vue)
// 初始化extend,cid
initExtend(Vue)
initAssetRegisters(Vue)
}
其中,options._base存储就是Vue构造函数,组件最后都会继承Vue构造函数,意思就是所有的组件options._base都是Vue。
{
config: {
optionMergeStrategies: Object.create(null),
silent: false,
productionTip: process.env.NODE_ENV !== 'production',
devtools: process.env.NODE_ENV !== 'production',
performance: false,
errorHandler: null,
warnHandler: null,nore certain custom elements
ignoredElements: [],
keyCodes: Object.create(null),
isReservedTag: no,
isReservedAttr: no,
isUnknownElement: no,
getTagNamespace: noop,
parsePlatformTagName: identity,
mustUseProp: no,
async: true,
_lifecycleHooks: LIFECYCLE_HOOKS
},
// util暴露的方法不建议使用
util:{
warn,
extend,
mergeOptions,
defineReactive
},
set: set,
delete: del,
nextTick: nextTick,
observable: function,
// 基础配置
options: {
components: {
KeepAlive
},
directives: {},
filters: {},
_base: Vue
},
use: funtion,
// 全局mixin
mixin: funtion,
// 全局extend
cid: 0,
extend: function,
// 全局组件,filter,指令注册
compnent: function,
filter: function,
directive: function,
}
为Vue添加静态方法之后,又被src/platforms/web/runtime/index.js引用,为Vue添加平台所需要的方法,以下web平台相关的,以下:
// install platform specific utils
Vue.config.mustUseProp = mustUseProp
// 是否保留标签,html和svg标签
Vue.config.isReservedTag = isReservedTag
// 是否style,class属性
Vue.config.isReservedAttr = isReservedAttr
// 获取svg,math命名空间
Vue.config.getTagNamespace = getTagNamespace
// 判断是否合法的html标签
Vue.config.isUnknownElement = isUnknownElement
// install platform runtime directives & components
// 混合model和show指令
extend(Vue.options.directives, platformDirectives)
// 混合transition,TransitionGroup内置组件
extend(Vue.options.components, platformComponents)
// install platform patch function
Vue.prototype.__patch__ = inBrowser ? patch : noop
// public mount method
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {}
为Vue.config添加了web环境下具体的实现,添加了v-mode和v-show指令,添加了transition,TransitionGroup内置组件,向Vue.prototype添加了__patch__和$mount方法。
接下来就到了最后一步,打开web/entry-runtime-with-compiler.js,这里就不贴相关代码,就是重写$mount方法,使其拥有编译的能力。也就是平时用于开发的版本,可以将写的模板编译成render函数。开发环境中,Vue首先会把我们写的单文件组件编译成render函数,然后再进行挂载。