整体架构
Vue框架采用组件化架构,通过响应式原理和虚拟DOM实现高效更新。以下是其核心工作机制:
1. 响应式系统
Vue通过ES5的Object.defineProperty()(Vue2)或ES6的Proxy(Vue3)劫持数据变更:
// 简化的响应式原理示例
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
// 依赖收集:记录哪个组件使用了这个数据
return val;
},
set(newVal) {
if (val !== newVal) {
val = newVal;
// 派发更新:通知所有依赖的组件重新渲染
updateComponent();
}
}
});
}
- 依赖收集:当组件渲染时,会记录哪些数据被访问(称为“依赖”)。
- 派发更新:数据变更时,通知所有依赖的组件重新渲染。
2. 模板编译
Vue将HTML模板编译为渲染函数(render functions):
// 模板
<div id="app">{{ message }}</div>
// 编译后的渲染函数
render() {
return createElement('div', {
attrs: { id: 'app' }
}, this.message);
}
- 编译过程:模板 → 抽象语法树(AST) → 渲染函数。
- 渲染函数返回虚拟DOM节点(VNode)。
3. 虚拟DOM与diff算法
- 虚拟DOM:轻量级JavaScript对象,是真实DOM的抽象表示。
- diff算法:比较新旧VNode的差异,最小化真实DOM操作:
// 简化的diff逻辑
function patch(oldVnode, newVnode) {
if (oldVnode === newVnode) return;
// 比较节点差异,只更新变化的部分
updateProperties(oldVnode, newVnode);
patchChildren(oldVnode.children, newVnode.children);
} - 批量更新:多次数据变更会合并为一次DOM更新(通过
nextTick实现)。
4. 生命周期钩子
Vue实例有完整的生命周期,提供钩子函数(如created、mounted、updated):
new Vue({
data() {
return { count: 0 };
},
created() {
// 数据初始化后执行
console.log('实例已创建');
},
mounted() {
// DOM渲染完成后执行
console.log('DOM已挂载');
}
});
5. 组件化与事件系统
- 组件树:每个组件有独立的作用域和状态。
- 单向数据流:数据流动是单向的(父 → 子),子组件通过
$emit触发事件通知父组件。
6. Vue3的优化
- Proxy代理:替代
Object.defineProperty(),支持深层响应式和数组优化。 - 组合式API(Composition API):更好的逻辑复用和代码组织。
- Tree-shaking:按需打包,减少体积。
总结
Vue通过响应式数据绑定和虚拟DOM的高效diff算法,实现了数据变更到DOM更新的自动映射,同时通过组件化和生命周期管理提升了代码可维护性。