先看一下源碼中關(guān)于Vue函數(shù)的定義(稍稍簡化),摘自Vue 2.6.11。
function Vue (options) {
if (!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword');
}
this._init(options); // 調(diào)用Vue.prototype._init函數(shù), this指向的就是Vue實例對象了
}
//調(diào)用一系列方法
initMixin(Vue); // 初始化,調(diào)用initMixin函數(shù),傳入Vue構(gòu)造函數(shù)
stateMixin(Vue);
eventsMixin(Vue);
lifecycleMixin(Vue);
renderMixin(Vue);
function initMixin (Vue) {
Vue.prototype._init = function (options) {
var vm = this; // vm被賦值為實例對象
vm._uid = uid$3++; // 當(dāng)觸發(fā)init方法,新建Vue實例時(當(dāng)渲染組件時也會觸發(fā))uid都會遞增
// 加入標(biāo)志防止該對象對observer監(jiān)聽
vm._isVue = true;
// 合并options
if (options && options._isComponent) { // 當(dāng)是組件時
// 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 { // 當(dāng)不是組件時
// 將合并后的options賦值給實例對象的$options
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
);
}
initProxy(vm);
// 實例對象的_self指向自己, 暴露出去
// 各種初始化
initLifecycle(vm);
initEvents(vm);
initRender(vm);
callHook(vm, 'beforeCreate'); // 觸發(fā)beforeCreate生命周期函數(shù)
initInjections(vm); // resolve injections before data/props
initState(vm);
initProvide(vm); // resolve provide after data/props
callHook(vm, 'created'); // 觸發(fā)created生命周期函數(shù)
// 掛載el
if (vm.$options.el) {
vm.$mount(vm.$options.el);
}
};
}
看看
Vue就是一個函數(shù),當(dāng)然可以把它理解為構(gòu)造函數(shù)和類,她只能用new 來生成實例對象。
我們平常使用引入Vue的方式就是:
var vm = new Vue({
el: '#app',
data: {
showA: false
},
beforeCreate(){
},
created(){
},
mounted(){
},
methods: {
}
});
// 可以打印出如下的數(shù)據(jù)
console.log(vm instanceof Vue); // true;
console.log(vm._self === vm); // true;
console.log(vm._isVue); // true;
console.log(vm._uid ); // 0; // 只有一個實例且沒有組件就是0
console.log(vm.$options); // 生成后的options
_init函數(shù)最重要的兩個部分就是:
1.初始化各種狀態(tài),然后調(diào)用
beforeCreated和created生命周期函數(shù)。
2.合并options生成 $options, 然后掛載。
看看$options的由來:
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
);
resolveConstructorOptions函數(shù)生成的對象含有:components,directives, filters,
然后再進行合并:
最后得出的$options,含有:
{
components: {}
directives: {}
filters: {}
_base: ? Vue(options)
el: "#app"
data: ? mergedInstanceDataFn()
mounted: [?]
methods: { beforeEnter: ?, enter: ?, leave: ?, changeShow: ?}
render: ? anonymous( )
staticRenderFns: []
}
然后去調(diào)用$amount函數(shù),執(zhí)行掛載。