151 lines
3.7 KiB
Markdown
151 lines
3.7 KiB
Markdown
|
# Vue2 组件系统深度解析
|
|||
|
|
|||
|
## 一、组件构造函数原理
|
|||
|
|
|||
|
### 1. Vue.extend 核心机制
|
|||
|
```javascript
|
|||
|
const School = Vue.extend({
|
|||
|
name: "School",
|
|||
|
template: `...`,
|
|||
|
data() {
|
|||
|
return {
|
|||
|
name: "Bunny",
|
|||
|
address: "昆山县印象花园"
|
|||
|
};
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
// 每次调用返回全新的构造函数
|
|||
|
console.log(School); // ƒ VueComponent(options) { this._init(options); }
|
|||
|
```
|
|||
|
|
|||
|
### 2. 组件实例化过程
|
|||
|
1. **模板编译**:将template编译为render函数
|
|||
|
2. **选项合并**:合并Vue全局配置和组件选项
|
|||
|
3. **构造函数生成**:基于Vue基类创建子类
|
|||
|
4. **实例化**:通过`new Component(options)`创建实例
|
|||
|
|
|||
|
## 二、组件注册方式对比
|
|||
|
|
|||
|
| 注册方式 | 语法 | 作用域 | 生命周期 |
|
|||
|
| -------- | ----------------------- | -------------- | ------------ |
|
|||
|
| 全局注册 | `Vue.component()` | 全应用可用 | 与根实例相同 |
|
|||
|
| 局部注册 | `components`选项 | 当前组件作用域 | 独立生命周期 |
|
|||
|
| 动态注册 | `Vue.extend()`+手动挂载 | 灵活控制 | 手动管理 |
|
|||
|
|
|||
|
## 三、组件核心特性详解
|
|||
|
|
|||
|
### 1. 组件选项合并策略
|
|||
|
```javascript
|
|||
|
const Parent = Vue.extend({
|
|||
|
created() {
|
|||
|
console.log('Parent Hook');
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
const Child = Parent.extend({
|
|||
|
created() {
|
|||
|
console.log('Child Hook');
|
|||
|
}
|
|||
|
});
|
|||
|
// 执行顺序:Parent Hook → Child Hook
|
|||
|
```
|
|||
|
|
|||
|
### 2. 组件隔离机制
|
|||
|
- **独立作用域**:每个组件实例维护独立的数据副本
|
|||
|
- **样式隔离**:通过scoped CSS实现
|
|||
|
- **命名空间**:基于组件树结构的$parent/$children关系
|
|||
|
|
|||
|
### 3. 性能优化技巧
|
|||
|
```javascript
|
|||
|
// 1. 异步组件
|
|||
|
const AsyncComp = () => ({
|
|||
|
component: import('./MyComp.vue'),
|
|||
|
loading: LoadingComp,
|
|||
|
error: ErrorComp
|
|||
|
});
|
|||
|
|
|||
|
// 2. 函数式组件
|
|||
|
const FuncComp = {
|
|||
|
functional: true,
|
|||
|
render(h, context) {
|
|||
|
// 无状态、无实例
|
|||
|
}
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
## 四、高级开发模式
|
|||
|
|
|||
|
### 1. 动态组件工厂
|
|||
|
```javascript
|
|||
|
function createComponent(template, data) {
|
|||
|
return Vue.extend({
|
|||
|
template,
|
|||
|
data() {
|
|||
|
return {...data};
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
### 2. 组件继承扩展
|
|||
|
```javascript
|
|||
|
const BaseList = Vue.extend({
|
|||
|
methods: {
|
|||
|
fetchData() {
|
|||
|
// 基础实现
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
const UserList = BaseList.extend({
|
|||
|
methods: {
|
|||
|
fetchData() {
|
|||
|
// 扩展实现
|
|||
|
super.fetchData();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
```
|
|||
|
|
|||
|
### 3. 组件通信体系
|
|||
|
| 通信方式 | 适用场景 | 示例 |
|
|||
|
| -------------- | -------- | ------------------------------------------ |
|
|||
|
| Props/Events | 父子组件 | `<Child :value="data" @input="handle">` |
|
|||
|
| Provide/Inject | 跨级组件 | `provide: { value: 1 }, inject: ['value']` |
|
|||
|
| Event Bus | 任意组件 | `Vue.prototype.$bus = new Vue()` |
|
|||
|
| Vuex | 复杂状态 | 集中式状态管理 |
|
|||
|
|
|||
|
## 五、调试与问题排查
|
|||
|
|
|||
|
### 1. 组件实例检查
|
|||
|
```javascript
|
|||
|
mounted() {
|
|||
|
console.log(this.$options.name); // 组件名
|
|||
|
console.log(this.$parent); // 父实例
|
|||
|
console.log(this.$children); // 子实例
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
### 2. 常见问题解决方案
|
|||
|
1. **模板不渲染**:
|
|||
|
- 检查组件是否正确定义和注册
|
|||
|
- 验证template/content是否有效
|
|||
|
|
|||
|
2. **数据不更新**:
|
|||
|
- 确认data是否为函数返回新对象
|
|||
|
- 检查props是否响应式
|
|||
|
|
|||
|
3. **生命周期异常**:
|
|||
|
- 避免在beforeCreate访问data
|
|||
|
- 确保异步操作在mounted后执行
|
|||
|
|
|||
|
## 六、Vue3对比说明
|
|||
|
|
|||
|
| 特性 | Vue2 | Vue3 |
|
|||
|
| -------- | ----------- | --------------- |
|
|||
|
| 组件定义 | Options API | Composition API |
|
|||
|
| 继承机制 | Vue.extend | defineComponent |
|
|||
|
| 性能优化 | 手动配置 | 自动优化 |
|
|||
|
| 片段支持 | 单根节点 | 多根节点 |
|