vue源码实现
Vue 源码实现分析
Vue.js 的源码实现涵盖了响应式系统、虚拟 DOM、模板编译等多个核心模块。以下从关键部分展开分析:
响应式系统
Vue 2.x 使用 Object.defineProperty 实现数据劫持,通过 getter/setter 追踪依赖:
function defineReactive(obj, key) {
const dep = new Dep();
let val = obj[key];
Object.defineProperty(obj, key, {
get() {
if (Dep.target) dep.depend(); // 收集依赖
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 触发更新
}
});
}
Vue 3.x 改用 Proxy 实现,能监听动态新增属性和数组索引变化:
const reactive = (target) => {
return new Proxy(target, {
get(target, key, receiver) {
track(target, key); // 依赖收集
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
Reflect.set(target, key, value, receiver);
trigger(target, key); // 触发更新
return true;
}
});
};
虚拟 DOM 与 Diff 算法
Vue 通过 snabbdom 改良的虚拟 DOM 实现高效更新:
function patch(oldVnode, vnode) {
if (sameVnode(oldVnode, vnode)) {
patchVnode(oldVnode, vnode); // 精细化比较
} else {
const parent = oldVnode.parentNode;
createElm(vnode); // 创建新节点
parent.insertBefore(vnode.elm, oldVnode);
parent.removeChild(oldVnode);
}
}
Diff 算法采用同级比较策略,通过双指针优化遍历效率。
模板编译
模板通过 compiler 转换为渲染函数:
- 解析器:将模板字符串转换为 AST(抽象语法树)
- 优化器:标记静态节点以跳过 Diff
- 代码生成器:生成可执行的
render函数
示例编译结果:
// 模板: <div>{{ message }}</div>
function render() {
return _c('div', [_v(_s(message))]);
}
组件系统
组件实例化流程:
- 合并选项(
mergeOptions) - 初始化生命周期(
initLifecycle) - 建立父子组件关联(
$parent/$children) - 触发
beforeCreate到mounted钩子
源码结构
典型模块分布:

core/:响应式、虚拟 DOM、组件核心compiler/:模板编译逻辑platforms/:平台相关代码(Web/Weex)sfc/:单文件组件解析
可通过调试 node_modules/vue/dist/vue.esm.js 或克隆 Vue GitHub 仓库 深入探索。






