一、VueComponent 的本质
从 4.VueComponent.html 中我们可以看到 Vue 组件的核心概念:
1. VueComponent 的构造函数
组件本质上是一个名为 VueComponent 的构造函数,这个函数不是由程序员直接定义的,而是通过 Vue.extend() 方法生成的。这个过程是 Vue 框架内部完成的,开发者只需关注组件的配置。
2. 组件的实例化过程
当我们使用 <school></school> 这样的标签时,Vue 在解析模板时会自动创建该组件的实例对象。实际上,Vue 在背后执行了 new VueComponent(options) 的操作。
3. 每次都是全新的组件
一个重要的细节是:每次调用 Vue.extend() 返回的都是一个全新的 VueComponent 构造函数 。这意味着即使使用相同的配置多次调用 Vue.extend(),也会得到不同的组件构造函数。
4. this 指向的差异
Vue 中有两种不同的 this 上下文:
-
组件配置中 (通过
Vue.extend创建的组件):data()函数、methods中的函数、watch中的函数- 它们的 this 均指向 VueComponent 实例对象(vc)
-
Vue 根实例配置中 (通过
new Vue()创建的实例):render函数、computed中的函数、watch中的函数- 它们的 this 均指向 Vue 实例对象(vm)
5. 术语说明
- VueComponent 实例对象 :简称为 vc(组件实例对象)
- Vue 实例对象 :简称为 vm(Vue 根实例)
二、原型链的重要关系
5.一个重要的内置关系.html 揭示了 Vue 组件系统的核心机制:
1. 关键的原型链关系
javascript
复制下载
ini
VueComponent.prototype.__proto__ === Vue.prototype
这个关系是 Vue 组件系统的基石,它建立了组件构造函数与 Vue 根构造函数之间的原型链连接。
2. 为什么需要这个关系?
这个原型链关系的存在有重要意义:
- 共享属性和方法:让所有组件实例对象(vc)都能访问到 Vue 原型上定义的属性和方法
- 实现继承机制 :组件可以继承 Vue 原型上的功能,如
$on,$emit,$nextTick等方法 - 统一 API 接口:保证了组件实例与 Vue 根实例在使用体验上的一致性
3. 实际应用示例
在代码示例中:
javascript
复制下载
css
const school = Vue.extend({
template: `
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
data() {
return {
name: '茶啊二中',
address: '江西'
}
}
});
当我们使用 <school></school> 组件时:
- Vue 创建
school组件的实例(vc) - 通过原型链
vc.__proto__.__proto__可以访问到Vue.prototype上的方法 - 因此组件实例也能使用
$emit,$on等 Vue 提供的方法
三、组件系统的整体架构
1. 构造函数关系图
text
复制下载
javascript
VueComponent (组件构造函数)
│
│ 通过 Vue.extend() 创建
│
▼
VueComponent.prototype
│
│ __proto__ 指向
│
▼
Vue.prototype
│
│ __proto__ 指向
│
▼
Object.prototype
2. 实例对象关系图
text
复制下载
javascript
vc (组件实例)
│
│ __proto__ 指向
│
▼
VueComponent.prototype
│
│ __proto__ 指向
│
▼
Vue.prototype
│
│ __proto__ 指向
│
▼
Object.prototype
四、开发实践启示
1. 全局方法的共享
由于原型链关系的存在,我们可以将一些公共方法添加到 Vue 原型上,这样所有组件都能访问:
javascript
复制下载
javascript
// 在 Vue 根实例创建前
Vue.prototype.$myMethod = function() {
console.log('这是一个全局方法');
}
// 在任何组件中都可以使用
// this.$myMethod()
2. 理解组件的独立性
虽然组件可以通过原型链访问 Vue 的原型方法,但每个组件实例仍然是独立的:
- 每个组件都有自己的数据(通过
data()返回) - 每个组件都有自己的生命周期
- 组件间的数据默认是隔离的
3. 避免混淆 this 上下文
在开发中需要注意不同上下文中 this 的指向:
- 在组件方法中,this 指向当前组件实例(vc)
- 在根实例方法中,this 指向 Vue 根实例(vm)
- 箭头函数会改变 this 的绑定,需要谨慎使用
五、总结
Vue 的组件系统通过巧妙的原型链设计,实现了以下目标:
- 组件复用性 :通过
Vue.extend()可以轻松创建可复用的组件 - 功能继承性:组件可以继承 Vue 原型上的功能,减少代码重复
- 架构一致性:保持了组件实例与根实例在使用上的一致性
- 系统扩展性:便于添加全局功能和方法
理解 VueComponent.prototype.__proto__ === Vue.prototype 这一关系,是深入掌握 Vue 组件机制的关键。这不仅帮助我们更好地使用 Vue,也为理解其他类似框架的设计原理提供了思路。
这种原型链设计模式体现了 JavaScript 原型继承的优雅之处,也是 Vue 框架设计精妙的一个例证。通过这种机制,Vue 在保持组件独立性的同时,实现了功能的共享和继承,为开发者提供了强大而灵活的组件系统。