上一节讲到了 Vue.extend 与 VueComponent 的区别,这一节讲一讲 Vue 与 VueComponent的内置关系。
原型与原型链
这里需要用到原型与原型链中的知识点,具体文章链接在这里。js中的原型与原型链
这里只需要理解一个点,那就是构造函数的prototype 属性(显式原型属性) === 实例对象的 __proto__属性(隐式原型属性),注意,这里只针对属性,至于属性所指向的原型对象,都是同一个。
function Demo() { }
const d = new Demo()
console.log(Demo.prototype) // 显式原型属性
console.log(d.__proto__) // 隐式原型属性
console.log(Demo.prototype === d.__proto__) // true
Vue.prototype === VueComponent.prototype.__proto__
了解了原型与原型链之后,我们就可以来看一下, Vue 与 VueComponent 之间的关系了。
Vue:构造函数
vm:通过 new Vue(option) 之后,得到的是 Vue的实例对象
VueComponent:也是构造函数,通过 Vue.extend(option) 之后,返回的 VueComponent函数
1、 Vue 构造函数里面有一堆东西,比如 cinfig 属性,注册全局组件的 component 属性等等。console.dir(Vue)即可查看。但是不说别的,肯定是有 prototype 显式原型属性的。拿到 Vue.prototype ,此时 Vue.prototype 指向的是 Vue构造函数的原型对象。
2、vm 就是 Vue 的实例对象,该对象上肯定存在一个 __proto__ 隐式原型属性。拿到 vm.__proto__ ,此时 vm.__proto__ 指向的也是 构造函数Vue 的 原型对象。
3、验证一下就是 控制台输出 Vue.prototype === vm.__proto__ (true)
4、构造函数 Vue 的原型对象也是一个对象,也存在 __proto__ 属性,但是 Vue.prototype.__proto__ 指向的是 Object,而Object.__proto__指向的是 null
5、VueComponent 类比 Vue ,同样是构造函数,VueComponent .prototype 指向的是 VueComponent 构造函数的原型对象。
6、通过 注册组件之后应用,Vue 自动帮我们 使用 New VueComponent() 生成了一个实例对象,这里叫他vc,以便于后续操作。vc实例对象类比 vm,存在 __proto__ 属性,vc.__proto__ 属性指向的也是是 VueComponent 构造函数的原型对象。
7、验证一下就是 控制台输出 VueComponent .prototype === vc.__proto__ (true)
8、构造函数 VueComponent 的原型对象也是一个对象,也存在 __proto__ 属性,按理来说是 VueComponent .prototype.__proto__ 指向的同样是是 Object。但是 Vue 做了一个处理,让 VueComponent .prototype.__proto__ 强制性指向了 Vue.prototype。
也就是上面说的 VueComponent .prototype.__proto__ === Vue.prototype
之所以这样强制指向,是为了让组件实例对象( vc )能够访问到 Vue原型上的属性与方法。
因为 Vue 原型上的方法和属性,按理来说只能是 构造函数 Vue 的实例对象才能使用。组件实例对象vc是用不了的,因为这两搭不上边,但是强制指向之后,通过原型链访问,vc就能使用 Vue原型上的属性和方法了。