一个简化版的Vue2框架实现,用于学习和理解Vue2的核心原理。本项目实现了Vue2的主要特性,包括响应式系统、虚拟DOM、模板编译和组件生命周期等。
本项目是一个教学用的Vue2框架简化实现,包含了Vue2的核心功能:
- ✅ 响应式数据系统 - 基于Object.defineProperty的数据劫持
- ✅ 虚拟DOM系统 - VNode创建和patch算法
- ✅ 模板编译系统 - HTML模板到render函数的转换
- ✅ 组件生命周期 - 完整的生命周期钩子支持
- ✅ 依赖收集与更新 - Watcher和Dep的观察者模式
- ✅ 数组响应式处理 - 重写数组原型方法
- ✅ 全局API - Vue.mixin等全局方法
- 使用
Object.defineProperty劫持对象属性 - 支持嵌套对象的深度响应式
- 数组变更方法的响应式处理
- 依赖收集和派发更新机制
- 轻量级的VNode对象结构
- 高效的DOM创建和更新算法
- 支持元素节点和文本节点
- HTML模板解析为AST语法树
- AST转换为render函数代码
- 支持插值表达式
{{}}语法
- 完整的生命周期钩子
- 选项合并策略
- 组件状态初始化
d:\project\vue2_basic\
├── src/
│ ├── index.js # Vue构造函数入口
│ ├── init/ # 初始化相关模块
│ │ ├── index.js # _init和$mount方法
│ │ ├── initState.js # 状态初始化入口
│ │ ├── initData.js # data选项初始化
│ │ ├── initMethods.js # methods选项初始化
│ │ ├── initComputed.js # computed选项初始化
│ │ ├── initWatch.js # watch选项初始化
│ │ └── initProps.js # props选项初始化
│ ├── observer/ # 响应式系统
│ │ ├── index.js # Observer主类
│ │ ├── dep.js # 依赖管理器
│ │ ├── watcher.js # 观察者类
│ │ └── array.js # 数组响应式处理
│ ├── vnode/ # 虚拟DOM系统
│ │ ├── index.js # 渲染方法混入
│ │ └── patch.js # DOM更新算法
│ ├── compile/ # 模板编译系统
│ │ ├── index.js # 编译入口
│ │ ├── parseAst.js # HTML解析器
│ │ ├── generate.js # 代码生成器
│ │ └── rule.js # 正则表达式规则
│ ├── lifecycle.js # 生命周期管理
│ ├── global-api/ # 全局API
│ │ └── index.js # Vue.mixin等方法
│ └── utils/ # 工具函数
│ └── index.js # 选项合并策略
└── README.md # 项目文档
核心文件: src/observer/index.js
// 响应式原理
class Observer {
constructor(data) {
// 1. 标记对象已被观察
Object.defineProperty(data, "__ob__", { value: this });
// 2. 区分数组和对象处理
if (Array.isArray(data)) {
data.__proto__ = newArrayProtoMethods;
this.observerArray(data);
} else {
this.walk(data);
}
}
}特点:
- 使用
Object.defineProperty进行属性劫持 - 在getter中收集依赖,在setter中触发更新
- 递归处理嵌套对象
- 特殊处理数组的变更方法
核心文件: src/observer/dep.js, src/observer/watcher.js
// 依赖收集原理
class Dep {
depend() {
if (Dep.target) {
Dep.target.addDep(this);
}
}
notify() {
this.subs.forEach(sub => sub.update());
}
}工作流程:
- Watcher执行时设置
Dep.target - 访问响应式数据触发getter
- Dep收集当前Watcher为依赖
- 数据变化时Dep通知所有Watcher更新
核心文件: src/vnode/index.js, src/vnode/patch.js
// VNode结构
function vnode(tag, data, children, text) {
return {
tag, // 标签名
data, // 属性数据
children, // 子节点
text, // 文本内容
elm: null // 真实DOM引用
};
}特点:
- 轻量级的JavaScript对象
- 描述DOM结构的完整信息
- 支持高效的DOM操作
核心文件: src/compile/index.js
// 编译流程
export function compileToFunction(template) {
// 1. 解析HTML为AST
let ast = parseHtml(template);
// 2. 生成render函数代码
let code = generate(ast);
// 3. 创建可执行函数
let render = new Function("with(this){return " + code + "}");
return render;
}编译过程:
- 解析: HTML → AST语法树
- 生成: AST → render函数代码
- 执行: 代码字符串 → 可执行函数
import Vue from './src/index.js';
// 创建Vue实例
const app = new Vue({
el: '#app',
data() {
return {
message: 'Hello Vue2!',
count: 0
};
},
methods: {
increment() {
this.count++;
}
},
mounted() {
console.log('组件已挂载');
}
});
// 数据变化会自动更新视图
app.message = 'Hello World!';
app.increment();<!-- HTML模板 -->
<div id="app">
<h1>{{message}}</h1>
<p>Count: {{count}}</p>
<button onclick="increment()">+1</button>
</div>┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ 数据变化 │───▶│ setter触发 │───▶│ Dep.notify │
└─────────────┘ └──────────────┘ └─────────────┘
│
┌─────────────┐ ┌──────────────┐ ┌─────▼─────┐
│ 视图更新 │◀───│ 重新渲染 │◀───│Watcher.run│
└─────────────┘ └──────────────┘ └───────────┘
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ 模板编译 │───▶│ render函数 │───▶│ VNode生成 │
└─────────────┘ └──────────────┘ └─────────────┘
│
┌─────────────┐ ┌──────────────┐ ┌─────▼─────┐
│ DOM更新 │◀───│ patch算法 │◀───│真实DOM创建│
└─────────────┘ └──────────────┘ └───────────┘
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│Watcher执行 │───▶│设置Dep.target │───▶│访问响应式数据│
└─────────────┘ └──────────────┘ └─────────────┘
│
┌─────────────┐ ┌──────────────┐ ┌─────▼─────┐
│建立依赖关系 │◀───│ dep.depend │◀───│getter触发 │
└─────────────┘ └──────────────┘ └───────────┘
| 特性 | 本项目实现 | Vue2官方 | 说明 |
|---|---|---|---|
| 响应式原理 | ✅ Object.defineProperty | ✅ 相同 | 核心原理一致 |
| 虚拟DOM | ✅ 简化版 | ✅ 完整版 | 实现了核心功能 |
| 模板编译 | ✅ 基础编译 | ✅ 完整编译 | 支持基本语法 |
| 组件系统 | ✅ 基础实现 | ✅ 完整实现 | 生命周期完整 |
| 指令系统 | ❌ 未实现 | ✅ 完整支持 | v-if、v-for等 |
| 事件系统 | ❌ 未实现 | ✅ 完整支持 | @click等事件 |
| 插槽系统 | ❌ 未实现 | ✅ 完整支持 | slot相关 |
| 性能优化 | 🔶 部分实现 | ✅ 完整优化 | 静态提升等 |
- 响应式系统原理
- 虚拟DOM概念
- 观察者模式
-
响应式系统 (
src/observer/)- Observer类的实现
- Dep和Watcher的关系
- 数组响应式处理
-
虚拟DOM系统 (
src/vnode/)- VNode结构设计
- patch算法实现
- DOM操作优化
-
模板编译 (
src/compile/)- HTML解析过程
- AST构建原理
- 代码生成机制
-
生命周期 (
src/lifecycle.js)- 组件挂载流程
- 更新机制
- 钩子函数调用
- 选项合并策略
- 全局API设计
- 性能优化技巧
- 观察者模式: Dep和Watcher的关系
- 发布订阅模式: 事件系统的基础
- 工厂模式: VNode的创建
- 策略模式: 选项合并策略
- 递归遍历: 响应式数据的深度处理
- 栈数据结构: HTML解析中的标签匹配
- 状态机: 模板编译的解析过程
- 批量更新: 异步更新队列
- 依赖收集: 精确的更新范围
- 异步更新: 批量DOM操作
- 对象复用: 减少内存分配
- 惰性计算: 按需编译和计算
如果要继续完善这个项目,可以考虑添加:
- 指令系统 - v-if、v-for、v-model等
- 事件系统 - @click、@input等事件处理
- 插槽系统 - slot和slot-scope
- 过滤器 - filter功能
- mixins - 更完善的混入机制
- 计算属性 - computed的完整实现
- 监听器 - watch的完整实现
- 组件通信 - props、emit等
欢迎提交Issue和Pull Request来完善这个项目!
MIT License
注意: 这是一个教学项目,仅用于学习Vue2的实现原理,不建议在生产环境中使用。