目录
框架概述与架构设计
Vue.js 是一个渐进式 JavaScript 框架,以其简洁的 API 和高效的性能而闻名。Vue 的源码架构设计体现了现代前端框架的最佳实践,采用模块化设计理念,各个功能模块可以独立工作并协同配合。
Vue 源码目录结构
Vue3 采用 Monorepo 架构,将源码拆分为多个独立的 npm 包,每个包负责不同的功能模块:
vue-next/├── packages/│ ├── compiler-core/ # 核心编译逻辑│ ├── compiler-dom/ # DOM特定的编译逻辑│ ├── compiler-sfc/ # 单文件组件编译│ ├── reactivity/ # 响应式系统核心│ ├── runtime-core/ # 运行时核心│ ├── runtime-dom/ # DOM运行时│ ├── shared/ # 共享工具函数│ └── vue/ # 主入口包├── scripts/ # 构建脚本├── test-dts/ # TypeScript类型测试└── typings/ # 类型定义
这种模块化设计使得各个功能模块可以独立开发、测试和发布,同时也方便了 Tree-shaking 优化。
核心架构图

Vue 的核心架构遵循 MVVM 模式,将视图 (View)、模型 (Model) 和视图模型 (ViewModel) 清晰分离:
- View:用户界面,通过 DOM 渲染
- Model:数据模型,普通 JavaScript 对象
- ViewModel:Vue 实例,负责数据绑定和 DOM 监听
响应式系统深度解析
响应式系统是 Vue 的核心特性,负责追踪数据变化并自动更新视图。Vue3 对响应式系统进行了全面重构,采用 Proxy 替代了 Vue2 的 Object.defineProperty。
Vue2 响应式原理
Vue2 使用Object.defineProperty实现响应式:
function defineReactive(obj, key, val) { const dep = new Dep() Object.defineProperty(obj, key, { get() { dep.depend() return val }, set(newVal) { if (newVal === val) return val = newVal dep.notify() } })}
存在的局限性
- 无法检测对象属性的添加或删除
- 数组索引操作无法被检测
- 需要递归遍历所有属性
- 性能开销较大
Vue3 响应式原理
Vue3 采用 ES6 的 Proxy API 实现更强大的响应式系统:
const targetMap = new WeakMap()function reactive(target) { return new Proxy(target, { get(target, key, receiver) { const result = Reflect.get(target, key, receiver) track(target, key) return isObject(result) ? reactive(result) : result }, set(target, key, value, receiver) { const oldValue = target[key] const result = Reflect.set(target, key, value, receiver) if (oldValue !== value) { trigger(target, key) } return result }, deleteProperty(target, key) { const hadKey = hasOwn(target, key) const result = Reflect.deleteProperty(target, key) if (hadKey) { trigger(target, key) } return result } })}

依赖收集与触发机制
Vue3 的响应式系统核心是依赖收集 (Track) 和触发更新 (Trigger) 机制:
function track(target, key) { if (!activeEffect) return let depsMap = targetMap.get(target) if (!depsMap) { depsMap = new Map() targetMap.set(target, depsMap) } let dep = depsMap.get(key) if (!dep) { dep = new Set() depsMap.set(key, dep) } dep.add(activeEffect) activeEffect.deps.push(dep)}function trigger(target, key) { const depsMap = targetMap.get(target) if (!depsMap) return const effects = new Set() const add = (effectsToAdd) => { if (effectsToAdd) { effectsToAdd.forEach(effect => effects.add(effect)) } } add(depsMap.get(key)) effects.forEach(effect => { if (effect.options.scheduler) { effect.options.scheduler(effect) } else { effect() } })}
Ref 与 Reactive 的区别
| 特性 | reactive | ref |
| 适用类型 | 对象 | 基本类型 |
| 是否可解构 | 否 | 是 |
| 内部实现 | Proxy 对象包装 | { value: xxx } |
| 访问方式 | 直接访问属性 | 通过.value 访问 |
虚拟 DOM 与 Diff 算法
虚拟 DOM 是 Vue 渲染系统的核心,它是对真实 DOM 的抽象表示。
虚拟 DOM 的概念
虚拟 DOM 是一个 JavaScript 对象,代表真实 DOM 节点的结构:
const vnode = { type: 'div', props: { id: 'app', class: 'container' }, children: [ { type: 'h1', children: 'Hello Vue!' }, { type: 'p', children: 'This is a paragraph' } ]}

Diff 算法原理
Vue 的 Diff 算法采用深度优先遍历和双端比较策略:
function patch(n1, n2, container) { if (n1 == null) { mountElement(n2, container) } else { if (n1.type !== n2.type) { unmount(n1) mountElement(n2, container) } else { patchElement(n1, n2) } }}function patchElement(n1, n2) { const el = (n2.el = n1.el) const oldProps = n1.props || {} const newProps = n2.props || {} // 更新属性 for (const key in newProps) { if (newProps[key] !== oldProps[key]) { patchProp(el, key, oldProps[key], newProps[key]) } } // 移除旧属性 for (const key in oldProps) { if (!(key in newProps)) { patchProp(el, key, oldProps[key], null) } } // 更新子节点 patchChildren(n1, n2, el)}
Vue3 Diff 算法优化
Vue3 的 Diff 算法相比 Vue2 有显著优化:
- 静态提升:将静态节点提升到渲染函数外部
- PatchFlag:标记动态节点类型,减少比较次数
- Block Tree:基于动态节点的区块化更新
- 事件缓存:缓存事件处理函数
编译系统工作原理
Vue 的编译系统负责将模板转换为渲染函数,这是 Vue 性能优化的重要环节。
编译流程
Vue 的编译过程分为三个主要阶段:
- 解析 (Parse):将模板字符串转换为抽象语法树 (AST)
- 转换 (Transform):对 AST 进行转换和优化
- 生成 (Generate):将转换后的 AST 生成渲染函数
// 编译入口function compile(template, options) { const ast = parse(template, options) transform(ast, options) return generate(ast, options)}
模板编译示例
输入模板:
<div id="app"> <h1>{{ title }}</h1> <p v-for="item in items">{{ item.text }}</p></div>
生成的渲染函数:
function render(_ctx) { return _openBlock(), _createBlock("div", { id: "app" }, [ _createVNode("h1", null, _toDisplayString(_ctx.title), 1 /* TEXT */), (_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.items, (item) => { return _createVNode("p", null, _toDisplayString(item.text), 1 /* TEXT */) }), 128 /* KEYED_FRAGMENT */)) ])}
编译时优化
Vue3 在编译阶段进行了多项优化:
- 静态分析:识别静态节点和动态节点
- 预计算:提前计算静态属性和样式
- 缓存优化:缓存静态节点和事件处理函数
- 类型检查:在编译阶段进行类型验证
组件生命周期与渲染流程
Vue 组件的生命周期管理是框架的核心功能之一,负责组件的创建、更新和销毁。
组件生命周期图

组件渲染流程
- 初始化阶段
- beforeCreate
- created
- beforeMount
- mounted
- 更新阶段
- beforeUpdate
- updated
- 销毁阶段
- beforeUnmount
- unmounted
渲染流程源码分析
function mountComponent(instance, container) { const { proxy, vnode } = instance // 创建渲染函数 const render = () => { return vnode.component.render.call(proxy) } // 创建副作用函数 const effect = new ReactiveEffect(render, () => { queueJob(instance.update) }) const update = () => effect.run() instance.update = update instance.effect = effect // 首次渲染 update() // 触发mounted钩子 queuePostRenderEffect(() => { instance.isMounted = true callWithAsyncErrorHandling(instance.mounted, instance, ErrorCodes.LIFECYCLE_HOOK) })}
性能优化机制
Vue3 在性能优化方面做了大量工作,相比 Vue2 有显著提升。
性能对比
| 指标 | Vue2 | Vue3 | 提升幅度 |
| 包体积 | 33KB | 19KB | 减少 41% |
| 初始渲染 | 基准 | 基准 + 55% | 提速 55% |
| 更新性能 | 基准 | 基准 + 133% | 提升 133% |
| 内存使用 | 基准 | 基准 – 54% | 减少 54% |
Tree-shaking 优化
Vue3 采用 ES 模块设计,配合 Rollup 实现 Dead Code Elimination:
// 按需导入import { ref, reactive } from 'vue'
基础运行时仅 12.5KB,大大减少了生产环境的包体积。
编译时优化
Vue3 的编译时优化主要体现在:
- 静态提升:将静态节点提升到渲染函数外部
- PatchFlag:标记动态节点类型
- Block Tree:基于动态节点的区块化更新
- 事件缓存:缓存事件处理函数
// 静态提升示例const _hoisted_1 = /*#__PURE__*/_createVNode("div", null, "Static Content", -1 /* HOISTED */)function render() { return (_openBlock(), _createBlock("div", null, [ _hoisted_1, _createVNode("span", null, _toDisplayString(_ctx.dynamic), 1 /* TEXT */) ]))}
响应式系统优化
Vue3 的响应式系统优化包括:
- 懒代理:访问属性时才递归代理
- WeakMap 优化:自动释放无引用对象
- Ref 优化:基本类型的响应式包装
- 计算属性缓存:避免重复计算
Vue3 与 Vue2 的核心差异
Vue3 相比 Vue2 在架构设计和实现原理上有重大改进。
架构设计差异
| 特性 | Vue2 | Vue3 |
| 响应式系统 | Object.defineProperty | Proxy |
| 源码组织 | 单体仓库 | Monorepo |
| 类型支持 | Flow | TypeScript |
| 包体积 | 完整打包 | 按需引入 |
| API 风格 | Options API | Composition API |
核心 API 对比
Vue2 Options API
export default { data() { return { count: 0, message: 'Hello' } }, methods: { increment() { this.count++ } }, computed: { doubleCount() { return this.count * 2 } }}
Vue3 Composition API
import { ref, computed } from 'vue'export default { setup() { const count = ref(0) const message = ref('Hello') const increment = () => { count.value++ } const doubleCount = computed(() => count.value * 2) return { count, message, increment, doubleCount } }}
性能提升总结
Vue3 相比 Vue2 的性能提升主要来自以下几个方面:
- 响应式系统重构:使用 Proxy 替代 Object.defineProperty
- 编译时优化:静态分析和动态标记
- Tree-shaking 支持:按需导入减少包体积
- 虚拟 DOM 优化:Block Tree 和 PatchFlag
- 事件系统优化:事件缓存和委托
总结
Vue 框架的源码设计体现了现代前端框架的最佳实践,从 Vue2 到 Vue3 的演进展示了框架设计的不断优化和创新。通过深入理解 Vue 的源码实现,我们可以更好地掌握框架的工作原理,编写出更高效、更优雅的 Vue 应用。
关键技术点回顾
- 响应式系统:基于 Proxy 的依赖收集和触发机制
- 虚拟 DOM:高效的 Diff 算法和渲染优化
- 编译系统:模板到渲染函数的转换和优化
- 组件系统:生命周期管理和组件通信
- 性能优化:编译时优化和运行时优化
学习建议
对于想要深入学习 Vue 源码的开发者,建议:
- 从核心模块入手:先理解响应式系统和虚拟 DOM
- 阅读官方文档:Vue.js 官方文档提供了详细的 API 说明
- 调试源码:通过断点调试理解代码执行流程
- 参与社区:加入 Vue 社区,与其他开发者交流学习
Vue 框架的设计理念和实现原理为前端开发提供了宝贵的学习资源,深入理解其源码不仅能帮助我们更好地使用框架,还能提升我们的编程能力和架构设计水平。











写的可以啊
不错