vue如何实现原理
Vue 的核心实现原理
Vue 的核心原理主要包括响应式系统、虚拟 DOM、模板编译和组件化。以下分模块详细说明其实现机制。
响应式系统
Vue 2.x 使用 Object.defineProperty 实现数据劫持,通过递归遍历数据对象的属性,将其转化为 getter/setter。当数据被访问或修改时,触发依赖收集和派发更新。
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log('get', key);
return val;
},
set(newVal) {
if (newVal !== val) {
console.log('set', key);
val = newVal;
}
}
});
}
Vue 3.x 改用 Proxy 实现响应式,解决了 Vue 2.x 对数组和新增属性的监听限制:

function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
console.log('get', key);
return Reflect.get(target, key);
},
set(target, key, val) {
console.log('set', key);
return Reflect.set(target, key, val);
}
});
}
虚拟 DOM 与 Diff 算法
Vue 通过虚拟 DOM 描述真实 DOM 结构,数据变化时生成新的虚拟 DOM,通过 Diff 算法对比新旧虚拟 DOM 的差异,最小化 DOM 操作:
function patch(oldVnode, newVnode) {
if (sameVnode(oldVnode, newVnode)) {
patchVnode(oldVnode, newVnode);
} else {
const parent = oldVnode.parentNode;
parent.replaceChild(createElm(newVnode), oldVnode.el);
}
}
Diff 算法采用同层比较策略,通过双端指针优化比对效率,优先处理常见场景如头尾节点相同的情况。

模板编译
Vue 模板通过编译生成渲染函数,分为以下步骤:
- 解析器将模板转换为 AST(抽象语法树)
- 优化器标记静态节点以跳过 Diff
- 代码生成器将 AST 转换为渲染函数代码
// 模板
<div id="app">{{ message }}</div>
// 编译后渲染函数
function render() {
with(this) {
return _c('div', { attrs: { "id": "app" } }, [_v(_s(message))]);
}
}
组件化实现
Vue 组件本质是可复用的 Vue 实例,通过 Vue.extend 创建子类构造函数。组件初始化时合并选项(如 mixins),建立父子组件关联,并管理生命周期钩子调用顺序。
const Child = Vue.extend({
template: '<div>Child Component</div>'
});
new Vue({
components: { Child },
template: '<child/>'
});
依赖收集与派发更新
每个响应式属性拥有自己的 Dep 实例,用于收集依赖的 Watcher。当数据变化时,通知所有依赖的 Watcher 执行更新:
class Dep {
constructor() {
this.subs = [];
}
depend() {
if (Dep.target) {
this.subs.push(Dep.target);
}
}
notify() {
this.subs.forEach(watcher => watcher.update());
}
}
组件渲染时创建渲染 Watcher,将当前 Watcher 设置为 Dep.target,触发 getter 进行依赖收集。






