vue底层实现远离
Vue 底层实现原理
Vue.js 的核心实现主要包括响应式系统、虚拟 DOM、模板编译和组件化机制。以下从关键模块分析其底层实现原理。
响应式系统
Vue 2.x 使用 Object.defineProperty 实现数据劫持,通过 getter/setter 拦截对象属性的访问和修改。每个响应式对象会关联一个 Dep 实例,用于收集依赖(Watcher)。当数据变化时,触发 setter 并通知 Dep 执行依赖更新。

// 简化版响应式实现
function defineReactive(obj, key, val) {
const dep = new Dep();
Object.defineProperty(obj, key, {
get() {
dep.depend(); // 收集依赖
return val;
},
set(newVal) {
val = newVal;
dep.notify(); // 触发更新
}
});
}
Vue 3.x 改用 Proxy 实现响应式,解决了 Object.defineProperty 无法监听数组和对象新增属性的限制。通过 Reflect 操作原始对象,Proxy 可以拦截更全面的操作(如 deleteProperty、has 等)。
虚拟 DOM 与 Diff 算法
Vue 将模板编译为渲染函数,生成虚拟 DOM(VNode)。当数据变化时,重新执行渲染函数生成新 VNode,通过 Diff 算法对比新旧 VNode:

- 同层比较:仅对比同一层级的节点,避免跨层级递归。
- Key 优化:通过
key标识节点身份,复用相同 key 的 DOM 元素。 - 双端比较:Vue 3 的 Diff 算法借鉴了 inferno 的双端交叉对比策略,减少移动操作次数。
// 简化版 VNode 结构
{
tag: 'div',
props: { class: 'container' },
children: [
{ tag: 'span', text: 'Hello' }
]
}
模板编译
Vue 的模板通过编译器转换为渲染函数,流程如下:
- 解析:将模板字符串解析为 AST(抽象语法树)。
- 优化:标记静态节点(不会变化的节点),避免 Diff 时重复处理。
- 生成代码:将 AST 转换为可执行的渲染函数代码。
// 模板示例
<div>{{ message }}</div>
// 编译后的渲染函数
function render() {
return _c('div', [_v(_s(message))]);
}
组件化机制
Vue 组件本质上是带有预设选项的 Vue 实例。组件初始化时:
- 合并配置:合并全局配置(如
Vue.mixin)和组件局部配置。 - 生命周期管理:调用
beforeCreate、created等钩子。 - 建立父子关系:通过
$parent和$children维护组件树结构。
Vue 3 的优化
- 模块化:使用 TypeScript 重写,核心模块可单独引用(如
@vue/reactivity)。 - Composition API:逻辑复用更灵活,替代 Options API 的 mixins。
- 性能提升:
- 静态树提升(Hoisting):将静态节点编译为常量,避免重复创建。
- 补丁标志(Patch Flags):标记动态绑定的类型,优化 Diff 过程。
关键源码结构
- 响应式:
packages/reactivity(Vue 3) - 虚拟 DOM:
src/core/vdom(Vue 2) - 编译器:
packages/compiler-core(Vue 3) - 运行时:
src/core/instance(Vue 2 的实例初始化逻辑)
通过上述机制,Vue 实现了数据驱动视图的高效更新,同时保持开发体验的简洁性。






