我们都知道new Vue()
将执行Vue
的构造函数,进而执行this_init
方法,那this,_init
在哪里 ,它做了哪些事?先来看看_init
函数的实现。
3.1、_init函数实现
Vue.prototype._init = function (options?: Object) {
const vm: Component = this//定义全局变量vm,等于初始化的vue对象
// a uid
vm._uid = uid++//当前Vue实例唯一标识
//非生产环境下进行性能监控
let startTag, endTag
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
startTag = `vue-perf-start:${
vm._uid}`
endTag = `vue-perf-end:${
vm._uid}`
mark(startTag)
}
// a flag to avoid this being observed
vm._isVue = true
// merge options对Vue 提供的 props、data、methods等选项进行合并处理
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
// 优化内部组件实例化,因为动态选项合并非常慢,而且没有一个内部组件选项需要特殊处理。
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {
},
vm
)
}
/* istanbul ignore else */
// 设置渲染函数的作用域代理,其目的是提供更好的提示信息(如:在模板内访问实例不存在的属性,则会在非生产环境下提供准确的报错信息)
if (process.env.NODE_ENV !== 'production') {
initProxy(vm)
} else {
vm._renderProxy = vm
}
// expose real self
// 暴露真实的实例本身
vm._self = vm
initLifecycle(vm)// 初始化生命周期
initEvents(vm)// 初始化事件
initRender(vm)//初始化render方法
callHook(vm, 'beforeCreate')// 调用生命周期钩子函数 -- beforeCreate
initInjections(vm) // resolve injections before data/props
initState(vm)//初始化 initProps、initMethods、initData、initComputed、initWatch
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created') //此时还没有任何挂载的操作,所以在 created 中是不能访问DOM的,即不能访问 $el
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
vm._name = formatComponentName(vm, false)
mark(endTag)
measure(`vue ${
vm._name} init`, startTag, endTag)
}
if (vm.$options.el) {
//页面挂载,数据更新,这里$moount调用的是entry-runtime-with-compiler.js中定义的方法
vm.$mount(vm.$options.el)
}
}
init函数实现的功能
- 在非生产环境下开启性能监控程序( 利用
Web Performance API
允许网页访问某些函数来测量网页和Web
应用程序的性能; ) - 对Vue提供的props,data,methods等进行合并处理
- 设置渲染函数作用域代理
- 执行相关初始化程序及电泳生命周期函数
- 根据挂载点调用挂在函数
3.2、选项合并处理
3.2.1、 mergeOptions
函数
该函数对我们传入的options做了一层处理,然后复制给实例属性$options,下面看看具体是怎么实现的。
function mergeOptions (
parent,
child,
vm
) {
if (process.env.NODE_ENV !== 'production')