测试代码
<div id="app">
<comp1></comp1>
</div>
<script>
const Com = Vue.component('comp1',{
template: '<div>com1</div>',
created () {
console.log(this.a) // 为什么可以访问a
},
})
Vue.prototype.a = 1
vm = new Vue({
el: '#app',
data: {
abc: 123
}
})
console.log(vm)
有如下3个问题:
- Com是什么?
- vm是什么?
- 为什么在子组件内部可以访问this.a?
答:
- Com是一个构造器(一个函数)
- Vue.component() 返回一个构造器。Vue.component是通过
src/core/global-api/assets.js
中的initAssetRegisters
循环添加的方法。
下面给出了部分伪代码:
Vue.component = function(option) {
// this.options._base === Vue 调用Vue.extend
definition = this.options._base.extend(definition)
return definition
}
Vue.extend = function () {
const Sub = function VueComponent (options) {
this._init(options)
}
// Sub.prototype = new Super()
// Object.create(Super.prototype)在不是很严谨的情况下,可以等价于 new Super()。只不过如果Super这个构造函数中有一些代码的话,Object.create()并不会执行它们。
Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
return Sub
}
这个构造器与Vue的关系是: Com.prototype.proto === Vue.prototype
如果再次通过 Com来创建某个实例c,即:
c = new Com()
则有 c.__proto_.__proto_ = Vue.prototype
综上,所有的vue 组件都可以通过原型链来访问Vue.prototype上的属性和方法。