🚀 Vue3 架构设计
Vue3 是一次完全重写,核心目标是更好的性能、更小的体积、更好的 TypeScript 支持。根据官方数据,Vue3 相比 Vue2:
41%
包体积减少
133%
初始化速度提升
110%
更新性能提升
120%
内存使用减少
Vue3 核心模块
@vue/reactivity
响应式系统(独立模块,可单独使用)
@vue/runtime-core
运行时核心(虚拟 DOM、组件系统)
@vue/compiler-core
编译器核心(模板 → 渲染函数)
@vue/shared
共享工具函数(类型、常量、工具)
💡 独特观点
Vue3 的真正突破不是"Composition API",而是编译时优化。通过静态分析,Vue3 在编译阶段就确定了哪些节点是动态的,从而避免不必要的 Diff。
⚡ 响应式系统源码
Vue3 的响应式系统是独立模块(@vue/reactivity),可以脱离 Vue 使用。核心是 Proxy 和 Effect。
1. 响应式系统核心原理
核心思想:使用 Proxy 拦截对象访问,通过 Effect 追踪依赖,数据变化时自动触发更新。
📝 简化版响应式系统实现
// 全局变量:当前活跃的 Effect
let activeEffect = null;
// 1. Effect:依赖追踪与触发
class Effect {
constructor(fn) {
this.fn = fn;
this.deps = []; // 依赖的集合(用于清理)
}
run() {
activeEffect = this;
const result = this.fn(); // 执行函数,触发 get 拦截
activeEffect = null;
return result;
}
}
// 2. Dep:依赖收集器(每个属性一个 Dep)
class Dep {
constructor() {
this.subscribers = new Set(); // 订阅者(Effect)集合
}
depend() {
if (activeEffect) {
this.subscribers.add(activeEffect);
activeEffect.deps.push(this); // 反向引用,用于清理
}
}
notify() {
this.subscribers.forEach(effect => effect.run()); // 触发更新
}
}
// 3. Reactive:创建响应式对象(使用 Proxy)
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
const dep = getDep(target, key); // 获取该属性的 Dep
dep.depend(); // 收集依赖(如果有活跃 Effect)
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
const dep = getDep(target, key); // 获取该属性的 Dep
dep.notify(); // 触发更新
return result;
}
});
}
// 辅助函数:为每个对象的每个属性创建 Dep
const targetMap = new WeakMap(); // obj → Map(key → Dep)
function getDep(target, key) {
let depsMap = targetMap.get(target);
if (!depsMap) {
depsMap = new Map();
targetMap.set(target, depsMap);
}
let dep = depsMap.get(key);
if (!dep) {
dep = new Dep();
depsMap.set(key, dep);
}
return dep;
}
// 4. 测试
const state = reactive({ count: 0 });
// 创建一个 Effect(会自动追踪依赖)
const effect = new Effect(() => {
console.log(`count is: ${state.count}`); // 访问 state.count,触发 get
});
effect.run(); // 输出:count is: 0
state.count++; // 修改 state.count,触发 set → 自动执行 effect.run()
// 输出:count is: 12. Vue3 源码中的响应式 API
reactive()
深层响应式(基于 Proxy)
import { reactive } from 'vue';
const state = reactive({ count: 0 });
state.count++; // 响应式ref()
响应式引用(包装为基本类型)
import { ref } from 'vue';
const count = ref(0);
count.value++; // 需要通过 .value 访问computed()
计算属性(惰性求值、缓存)
import { computed } from 'vue';
const doubled = computed(() => count.value * 2);watch() / watchEffect()
副作用监听
import { watch } from 'vue';
watch(() => state.count, (newVal, oldVal) => {
console.log(`count changed: ${oldVal} → ${newVal}`);
});📝 Vue3 源码:reactive() 简化实现
// packages/reactivity/src/reactive.ts
const reactiveMap = new WeakMap<object, any>(); // 缓存,避免重复代理
export function reactive(target: object) {
return createReactiveObject(
target,
false,
mutableHandlers, // get/set/deleteProperty... 拦截器
mutableCollectionHandlers,
reactiveMap
);
}
function createReactiveObject(
target,
isReadonly,
baseHandlers,
collectionHandlers,
proxyMap
) {
// 1. 如果已经是代理,直接返回
const existingProxy = proxyMap.get(target);
if (existingProxy) {
return existingProxy;
}
// 2. 创建代理
const proxy = new Proxy(target, baseHandlers);
// 3. 缓存代理
proxyMap.set(target, proxy);
return proxy;
}
// mutableHandlers(核心拦截器)
const mutableHandlers: ProxyHandler<object> = {
get(target, key, receiver) {
// 1. 访问 track(依赖收集)
track(target, key);
// 2. 返回值(如果是嵌套对象,递归代理)
const res = Reflect.get(target, key, receiver);
return isObject(res) ? reactive(res) : res;
},
set(target, key, value, receiver) {
// 1. 设置值
const result = Reflect.set(target, key, value, receiver);
// 2. 触发 trigger(通知更新)
trigger(target, key);
return result;
}
};📝 总结与展望
Vue3 源码是现代前端框架的经典案例。通过本文的学习,你应该掌握了:
🎯 核心要点
- 架构设计:模块化、独立响应式系统、编译时优化
- 响应式系统:Proxy、Effect、Dep、依赖收集、触发更新
- reactive():Proxy 拦截、深层代理、缓存
- ref():RefImpl 类、.value 访问、unref()
- computed():惰性求值、缓存、dirty 标志
- 虚拟 DOM:VNode、渲染函数、Patch 算法
- 编译优化:Block Tree、PatchFlags、静态提升
- 生命周期:beforeCreate、mounted、 unmount 实现
- 最佳实践:使用 Composition API、避免深层响应式、合理使用 computed
🚀 未来展望
Vue3 生态正在快速演进,值得关注的方向:
- Vapor Mode:无虚拟 DOM 模式(类似 Svelte)
- Vue Vine:基于函数的组件定义(FBV,Function-Based Components)
- Vue Macros:$defineProps、$defineEmits 宏(编译时)
- Vue 2.7:向后移植 Composition API 到 Vue 2
- Vue 与 React:越来越像(Hooks vs Composition API)