Vue3响应式系统原理
字数 457 2025-11-02 08:11:07
Vue3响应式系统原理
描述
Vue3的响应式系统是其核心机制,能够自动追踪数据依赖,在数据变化时触发相关组件的更新。该系统基于ES6的Proxy和Reflect API实现,相比Vue2的Object.defineProperty具有更强大的功能和更好的性能。
解题过程
-
核心目标分析
- 我们需要建立一个系统,当数据被读取时,能记录下"谁在读取它"(依赖收集)
- 当数据被修改时,能通知"所有读取过它的地方"进行更新(依赖触发)
-
基本实现原理
- 使用Proxy代理目标对象,拦截get/set操作
- 使用WeakMap、Map和Set构建依赖关系图
- 通过effect函数建立响应式依赖
-
详细实现步骤
步骤1:创建响应式对象
function reactive(target) { return new Proxy(target, { get(obj, key) { // 依赖收集:记录当前正在执行的effect track(obj, key) return Reflect.get(obj, key) }, set(obj, key, value) { const result = Reflect.set(obj, key, value) // 依赖触发:通知所有依赖这个属性的effect trigger(obj, key) return result } }) }步骤2:建立依赖收集系统
// 存储所有的依赖关系 const targetMap = new WeakMap() // WeakMap<target, Map<key, Set<effect>>> let activeEffect = null function track(target, key) { if (!activeEffect) return let depsMap = targetMap.get(target) if (!depsMap) { targetMap.set(target, (depsMap = new Map())) } let deps = depsMap.get(key) if (!deps) { depsMap.set(key, (deps = new Set())) } deps.add(activeEffect) }步骤3:实现依赖触发
function trigger(target, key) { const depsMap = targetMap.get(target) if (!depsMap) return const deps = depsMap.get(key) if (deps) { deps.forEach(effect => effect()) } }步骤4:创建effect函数
function effect(fn) { activeEffect = fn fn() // 执行函数,触发getter,收集依赖 activeEffect = null } -
完整工作流程示例
// 创建响应式对象 const state = reactive({ count: 0 }) // 建立响应式effect effect(() => { console.log('count发生了变化:', state.count) }) // 修改数据,自动触发effect state.count = 1 // 输出:"count发生了变化: 1" -
进阶特性实现
嵌套effect支持:
const effectStack = [] function effect(fn) { const execute = () => { cleanup(effect) // 清除旧依赖 activeEffect = effect effectStack.push(effect) fn() effectStack.pop() activeEffect = effectStack[effectStack.length - 1] } execute() }调度器实现:
function effect(fn, options = {}) { const effect = () => { // ...执行逻辑 } effect.scheduler = options.scheduler // 支持自定义调度 return effect }
通过这种设计,Vue3能够精确追踪每个属性的依赖关系,在数据变化时高效地触发更新,同时支持更复杂的响应式场景如嵌套effect、计算属性等。