vue底层实现原理
Vue 的响应式系统实现原理
Vue 的响应式系统基于 ES5 的 Object.defineProperty(Vue 2)或 ES6 的 Proxy(Vue 3)实现。通过劫持数据的访问和修改,自动触发依赖收集和更新。
Vue 2 的实现:
- 使用
Object.defineProperty递归遍历数据对象,为每个属性添加getter和setter。 - 在
getter中收集依赖(Watcher),在setter中通知依赖更新。 - 数组类型通过重写数组方法(如
push、pop)实现响应式。
// 简化版响应式实现
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log('收集依赖');
return val;
},
set(newVal) {
if (newVal === val) return;
console.log('触发更新');
val = newVal;
}
});
}
Vue 3 的实现:
- 使用
Proxy代理整个对象,无需递归遍历。 - 通过
Reflect操作对象属性,支持动态新增属性的响应式。
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
console.log('收集依赖');
return Reflect.get(target, key);
},
set(target, key, value) {
if (target[key] === value) return true;
console.log('触发更新');
return Reflect.set(target, key, value);
}
});
}
虚拟 DOM 与 Diff 算法
Vue 通过虚拟 DOM(Virtual DOM)优化渲染性能。虚拟 DOM 是真实 DOM 的轻量级 JavaScript 对象表示。
Diff 算法核心:
- 同级比较:只比较同一层级的节点,不跨级比较。
- Key 优化:通过
key标识节点,减少不必要的 DOM 操作。 - 双端比较(Vue 3):同时从新旧子节点的两端向中间比较,提升效率。
// 简化版虚拟 DOM 结构
const vnode = {
tag: 'div',
props: { class: 'container' },
children: [
{ tag: 'p', text: 'Hello Vue' }
]
};
模板编译过程
Vue 的模板通过编译器转换为渲染函数(Render Function),最终生成虚拟 DOM。

编译步骤:
- 解析(Parse):将模板字符串转换为抽象语法树(AST)。
- 优化(Optimize):标记静态节点,避免重复渲染。
- 生成(Generate):将 AST 转换为渲染函数代码。
// 示例模板
<template>
<div>{{ message }}</div>
</template>
// 编译后的渲染函数
function render() {
return h('div', this.message);
}
组件化机制
Vue 的组件本质上是可复用的 Vue 实例,通过 Vue.component 或单文件组件(SFC)定义。
组件核心流程:

- 初始化:合并配置项(如
data、methods),建立父子关系。 - 渲染:生成组件虚拟 DOM,通过
patch挂载到真实 DOM。 - 更新:响应式数据变化触发组件重新渲染。
生命周期钩子
Vue 组件的生命周期分为创建、挂载、更新、销毁四个阶段,每个阶段触发对应的钩子函数。
主要生命周期:
beforeCreate:实例初始化后,数据观测前。created:数据观测完成,但 DOM 未挂载。beforeMount:模板编译完成,即将挂载。mounted:DOM 挂载完成。beforeUpdate:数据变化,DOM 更新前。updated:DOM 更新完成。beforeDestroy:实例销毁前。destroyed:实例销毁完成。
异步更新队列
Vue 通过异步队列(nextTick)批量处理数据变更后的 DOM 更新,避免频繁重绘。
实现原理:
- 使用
Promise、MutationObserver或setTimeout实现异步调度。 - 同一事件循环内的数据变更会被合并为一次更新。
// 示例:nextTick 使用
this.message = 'updated';
Vue.nextTick(() => {
console.log('DOM 已更新');
});






