问题引入
Vue 中的组件实例是什么?是与根实例一样的 Vue 实例吗?
Vue 中的组件是什么?
我们知道 Vue 中的组件实例同样可以调用挂在 Vue. prototype 上面的方法,那 Vue 组件实例与根实例到底是什么关系呢?
答案是继承关系,Vue 组件的构造函数继承自 Vue 构造函数,所以 Vue 组件继承了 Vue. prototype 上面的原型方法。
可以说 Vue 组件实例与根实例大致类似,但在某些地方还是有不同之处。
原型式继承
原型式继承是借助原型可以基于已有的对象创建新的对象,新的对象可以与原有对象保持相似。原型式继承最初的实现如下:
function object(o){
function F(){}
F.prototype = o
return new F()
}
在 object 函数内部,先创建了一个临时的构造函数 F,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时构造函数 F 的新实例。
这种方式的前提是你必须要有一个基础对象 o ,经过 object(o) 之后,新创建的实例的原型对象指向的就是 o,所以新的实例对象可以向上查找并使用 o 的属性或者方法。换句话说,新创建的实例对象与 o 的属性及方法保持相似。
ESMAScript 通过新增
Object. create ()方法规范化了原型继承。
Vue 中组件的实现
我们知道 Vue 组件其实与 Vue 根实例大致类似,比如挂载到 Vue. prototype 上面的属性、方法在每个组件也都要可以使用。创建出相似的实例对象,这是原型式继承的绝佳场景。
Vue 中实现 component 的代码位于 src/core/vnode/create-component. ts 中, 其核心代码如下:
其中 baseCtor 是构造函数 Vue
isObject (Ctor) 中的 Ctor 是我们在定义 Vue 组件时的配置对象。在这条 if 语句中,Ctor = baseCtor.extend(Ctor as typeof Component) 表示把 Ctor 从一个配置对象变成一个构造函数。这个构造函数就是 Vue 中用于实例化组件的构造函数。
那么,extend 中做了什么?我理解主要做了两件事情:
- 创建
Vue组件的构造函数Sub,并通过Object. create方法使用原型继承自Vue. prototype - 对
Sub做一些其他的初始化,如将一些不能继承的静态方法(Vue.mixin、Vue.use)挂载到Sub上面。
extend 函数的代码如下:
图中的高亮部分展示了组件构造函数 Sub 通过 Object. create 继承了 Super(也就是 Vue),所以在 Vue 组件实例中我们一样可以挂在 Vue. prototype 上面的属性、方法。
总结
本文主要讲解了 Vue 中组件实例的实现,继而引出原型式继承的相关知识。希望大家通过本文能够对 Vue 中组件的实现方式能有更加清晰的认识,同时也加深对原型式继承的理解。希望对你有有所帮助。