Vue3 响应式系统深度解析:从依赖追踪到派发更新的完整指南

34 阅读5分钟

摘要

Vue3 的响应式系统是其核心特性,它通过 Proxy 和 Reflect API 实现了更强大、更高效的依赖追踪。本文将深入探讨 Vue3 响应式系统的工作原理、依赖收集、触发更新等核心机制,通过详细的代码示例、执行流程分析和性能对比,帮助你彻底掌握 Vue3 响应式系统的完整知识体系。


一、 Vue3 响应式系统概述

1.1 Vue2 响应式系统的局限性

Vue2 使用 Object.defineProperty 实现响应式:

// Vue2 响应式实现简例
function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`读取 ${key}: ${val}`)
      return val
    },
    set(newVal) {
      if (newVal !== val) {
        console.log(`设置 ${key}: ${newVal}`)
        val = newVal
      }
    }
  })
}

const data = { count: 0 }
defineReactive(data, 'count', data.count)

Vue2 响应式的痛点:

  • 无法检测属性添加/删除:需要使用 Vue.set/Vue.delete
  • 数组方法需要重写:通过修改数组原型方法实现响应式
  • 性能开销大:需要递归遍历所有属性
  • 内存占用高:每个属性都需要单独的 getter/setter

1.2 Vue3 响应式系统的优势

Vue3 使用 Proxy 实现响应式:

// Vue3 响应式实现简例
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      console.log(`读取 ${String(key)}`)
      return Reflect.get(target, key, receiver)
    },
    set(target, key, value, receiver) {
      console.log(`设置 ${String(key)}: ${value}`)
      return Reflect.set(target, key, value, receiver)
    }
  })
}

const data = reactive({ count: 0 })
data.count = 1 // 触发 set

Vue3 响应式的优势:

  • 全面拦截:可以拦截所有操作(增、删、改、查)
  • 更好的性能:惰性代理,按需响应
  • 更好的 TypeScript 支持:完整的类型推断
  • 更小的内存占用:不需要预先定义所有属性

二、 Vue3 响应式系统核心架构

2.1 响应式系统整体架构

流程图:Vue3 响应式系统完整工作流程

flowchart TD
    A[创建响应式对象] --> B[Proxy 拦截操作]
    B --> C{操作类型}
    
    C --> D[GET 操作]
    D --> E[追踪依赖<br>track]
    E --> F[记录effect-target映射]
    
    C --> G[SET 操作]
    G --> H[触发更新<br>trigger]
    H --> I[查找对应effect]
    I --> J[执行副作用函数]
    
    C --> K[其他操作<br>has/delete等]
    K --> L[相应处理]
    
    J --> M[组件重新渲染]
    M --> N[DOM 更新]

2.2 核心概念解析

  • Target:被代理的原始对象
  • Proxy:代理对象,拦截对 Target 的操作
  • Effect:副作用函数,当依赖变化时需要重新执行
  • Track:依赖收集,建立属性与 Effect 的映射关系
  • Trigger:派发更新,当属性变化时通知相关 Effect

三、 响应式系统核心实现原理

3.1 基础响应式实现

让我们从零开始实现一个简化的 Vue3 响应式系统:

// 简化版 Vue3 响应式系统实现
class ReactiveSystem {
  constructor() {
    this.targetMap = new WeakMap()  // 存储目标对象到依赖的映射
    this.activeEffect = null        // 当前活动的副作用函数
  }

  // 依赖收集
  track(target, key) {
    if (!this.activeEffect) return
    
    let depsMap = this.targetMap.get(target)
    if (!depsMap) {
      depsMap = new Map()
      this.targetMap.set(target, depsMap)
    }
    
    let dep = depsMap.get(key)
    if (!dep) {
      dep = new Set()
      depsMap.set(key, dep)
    }
    
    dep.add(this.activeEffect)
    console.log(`📌 追踪依赖: ${key} ->`, this.activeEffect.name)
  }

  // 派发更新
  trigger(target, key) {
    const depsMap = this.targetMap.get(target)
    if (!depsMap) return
    
    const dep = depsMap.get(key)
    if (dep) {
      console.log(`🚀 触发更新: ${key},影响 ${dep.size} 个副作用`)
      dep.forEach(effect => {
        if (effect.scheduler) {
          effect.scheduler()
        } else {
          effect()
        }
      })
    }
  }

  // 创建响应式对象
  reactive(obj) {
    const handler = {
      get(target, key, receiver) {
        console.log(`🔍 读取属性: ${String(key)}`)
        const result = Reflect.get(target, key, receiver)
        
        // 追踪依赖
        this.track(target, key)
        
        // 如果结果是对象,递归代理
        if (result !== null && typeof result === 'object') {
          return this.reactive(result)
        }
        
        return result
      }.bind(this),
      
      set(target, key, value, receiver) {
        console.log(`✏️ 设置属性: ${String(key)} = ${value}`)
        const oldValue = target[key]
        const result = Reflect.set(target, key, value, receiver)
        
        // 只有值真正改变时才触发更新
        if (oldValue !== value) {
          this.trigger(target, key)
        }
        
        return result
      }.bind(this),
      
      deleteProperty(target, key) {
        console.log(`🗑️ 删除属性: ${String(key)}`)
        const hadKey = Object.prototype.hasOwnProperty.call(target, key)
        const result = Reflect.deleteProperty(target, key)
        
        if (hadKey && result) {
          this.trigger(target, key)
        }
        
        return result
      }.bind(this)
    }
    
    return new Proxy(obj, handler)
  }

  // 创建副作用函数
  effect(fn, options = {}) {
    const effectFn = () => {
      this.activeEffect = effectFn
      const result = fn()
      this.activeEffect = null
      return result
    }
    
    effectFn.name = fn.name || 'anonymous'
    effectFn.scheduler = options.scheduler
    
    // 立即执行一次
    effectFn()
    
    return effectFn
  }
}

// 使用示例
const system = new ReactiveSystem()

// 创建响应式对象
const state = system.reactive({
  count: 0,
  user: {
    name: '张三',
    age: 25
  }
})

// 创建副作用函数
system.effect(function render() {
  console.log(`🎨 渲染: count = ${state.count}, name = ${state.user.name}`)
  document.getElementById('app').innerHTML = `
    <div>
      <h2>计数: ${state.count}</h2>
      <p>用户: ${state.user.name} (${state.user.age}岁)</p>
    </div>
  `
})

// 测试响应式
setTimeout(() => {
  state.count = 1  // 触发更新
}, 1000)

setTimeout(() => {
  state.user.name = '李四'  // 触发更新
}, 2000)

setTimeout(() => {
  state.user.age = 26  // 触发更新
}, 3000)

3.2 完整的响应式系统演示

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue3 响应式系统演示</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1000px;
            margin: 0 auto;
            padding: 20px;
            background: #f5f5f5;
        }
        .demo-container {
            background: white;
            border-radius: 12px;
            padding: 30px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.1);
            margin-bottom: 30px;
        }
        .controls {
            display: flex;
            gap: 15px;
            margin: 20px 0;
            flex-wrap: wrap;
        }
        button {
            padding: 10px 20px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.3s;
        }
        .btn-primary { background: #42b883; color: white; }
        .btn-secondary { background: #3498db; color: white; }
        .btn-warning { background: #e67e22; color: white; }
        .btn-danger { background: #e74c3c; color: white; }
        button:hover { opacity: 0.9; transform: translateY(-1px); }
        .log-container {
            background: #2c3e50;
            color: white;
            border-radius: 8px;
            padding: 20px;
            margin-top: 20px;
            max-height: 400px;
            overflow-y: auto;
            font-family: 'Courier New', monospace;
            font-size: 12px;
        }
        .log-item {
            padding: 8px 12px;
            margin: 4px 0;
            background: #34495e;
            border-radius: 4px;
            border-left: 4px solid #42b883;
        }
        .data-display {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin: 20px 0;
        }
        .data-card {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
            border: 1px solid #e9ecef;
        }
        .data-card h4 {
            margin: 0 0 10px 0;
            color: #2c3e50;
        }
    </style>
</head>
<body>
    <div class="demo-container">
        <h1>Vue3 响应式系统深度演示</h1>
        
        <div class="data-display">
            <div class="data-card">
                <h4>基本数据</h4>
                <div id="basic-data">计数: 0, 消息: Hello</div>
            </div>
            <div class="data-card">
                <h4>用户信息</h4>
                <div id="user-data">姓名: 张三, 年龄: 25</div>
            </div>
            <div class="data-card">
                <h4>计算属性</h4>
                <div id="computed-data">双倍计数: 0</div>
            </div>
            <div class="data-card">
                <h4>数组数据</h4>
                <div id="array-data">列表长度: 0</div>
            </div>
        </div>

        <div class="controls">
            <button class="btn-primary" onclick="incrementCount()">增加计数</button>
            <button class="btn-secondary" onclick="updateUser()">更新用户</button>
            <button class="btn-warning" onclick="addTodo()">添加待办</button>
            <button class="btn-danger" onclick="clearLogs()">清空日志</button>
            <button class="btn-secondary" onclick="addNewProperty()">添加新属性</button>
            <button class="btn-warning" onclick="deleteProperty()">删除属性</button>
        </div>

        <div class="log-container" id="log-container">
            <div class="log-item">🚀 响应式系统已启动...</div>
        </div>
    </div>

    <script>
        // 完整的 Vue3 响应式系统实现
        class Vue3ReactiveSystem {
            constructor() {
                this.targetMap = new WeakMap()
                this.activeEffect = null
                this.effects = new Set()
                this.logs = []
            }

            log(message, type = 'info') {
                const timestamp = new Date().toLocaleTimeString()
                const logItem = {
                    time: timestamp,
                    message,
                    type
                }
                this.logs.push(logItem)
                
                const logElement = document.createElement('div')
                logElement.className = 'log-item'
                logElement.style.borderLeftColor = 
                    type === 'error' ? '#e74c3c' : 
                    type === 'warn' ? '#f39c12' : '#42b883'
                logElement.innerHTML = `[${timestamp}] ${message}`
                
                const container = document.getElementById('log-container')
                container.appendChild(logElement)
                container.scrollTop = container.scrollHeight
                
                console.log(`[${type.toUpperCase()}] ${message}`)
            }

            track(target, key) {
                if (!this.activeEffect) return
                
                let depsMap = this.targetMap.get(target)
                if (!depsMap) {
                    depsMap = new Map()
                    this.targetMap.set(target, depsMap)
                }
                
                let dep = depsMap.get(key)
                if (!dep) {
                    dep = new Set()
                    depsMap.set(key, dep)
                }
                
                if (!dep.has(this.activeEffect)) {
                    dep.add(this.activeEffect)
                    this.log(`📌 追踪依赖: ${this.getTargetName(target)}.${key} -> ${this.activeEffect.name}`)
                }
            }

            trigger(target, key, type = 'SET') {
                const depsMap = this.targetMap.get(target)
                if (!depsMap) return
                
                const dep = depsMap.get(key)
                if (dep) {
                    this.log(`🚀 触发更新: ${this.getTargetName(target)}.${key} (${type}),影响 ${dep.size} 个副作用`)
                    dep.forEach(effect => {
                        if (effect.scheduler) {
                            effect.scheduler()
                        } else {
                            effect()
                        }
                    })
                }
            }

            getTargetName(target) {
                if (target === state) return 'state'
                if (target === state.user) return 'state.user'
                if (target === state.todos) return 'state.todos'
                return 'unknown'
            }

            reactive(obj, name = 'anonymous') {
                const handler = {
                    get: (target, key, receiver) => {
                        const result = Reflect.get(target, key, receiver)
                        
                        // 追踪依赖
                        this.track(target, key)
                        
                        // 递归代理对象和数组
                        if (result !== null && typeof result === 'object') {
                            return this.reactive(result, `${name}.${String(key)}`)
                        }
                        
                        return result
                    },
                    
                    set: (target, key, value, receiver) => {
                        const oldValue = target[key]
                        const result = Reflect.set(target, key, value, receiver)
                        
                        if (oldValue !== value) {
                            this.trigger(target, key, 'SET')
                        }
                        
                        return result
                    },
                    
                    deleteProperty: (target, key) => {
                        const hadKey = Object.prototype.hasOwnProperty.call(target, key)
                        const result = Reflect.deleteProperty(target, key)
                        
                        if (hadKey && result) {
                            this.trigger(target, key, 'DELETE')
                        }
                        
                        return result
                    },
                    
                    has: (target, key) => {
                        this.track(target, key)
                        return Reflect.has(target, key)
                    },
                    
                    ownKeys: (target) => {
                        this.track(target, 'ITERATE')
                        return Reflect.ownKeys(target)
                    }
                }
                
                return new Proxy(obj, handler)
            }

            effect(fn, options = {}) {
                const effectFn = () => {
                    try {
                        this.activeEffect = effectFn
                        return fn()
                    } finally {
                        this.activeEffect = null
                    }
                }
                
                effectFn.name = options.name || fn.name || 'anonymous'
                effectFn.scheduler = options.scheduler
                this.effects.add(effectFn)
                
                // 立即执行一次
                effectFn()
                
                return () => {
                    this.effects.delete(effectFn)
                }
            }

            computed(getter) {
                let dirty = true
                let value
                
                const effectFn = this.effect(getter, {
                    name: 'computed',
                    scheduler: () => {
                        if (!dirty) {
                            dirty = true
                            this.trigger(runner, 'value')
                        }
                    }
                })
                
                const runner = {
                    get value() {
                        if (dirty) {
                            value = effectFn()
                            dirty = false
                            system.track(runner, 'value')
                        }
                        return value
                    }
                }
                
                return runner
            }
        }

        // 创建响应式系统实例
        const system = new Vue3ReactiveSystem()

        // 创建响应式状态
        const state = system.reactive({
            count: 0,
            message: 'Hello Vue3',
            user: {
                name: '张三',
                age: 25,
                profile: {
                    level: 'VIP',
                    points: 1000
                }
            },
            todos: [],
            newProperty: '动态添加的属性'
        }, 'state')

        // 创建计算属性
        const doubleCount = system.computed(() => {
            return state.count * 2
        })

        // 注册副作用函数
        system.effect(() => {
            document.getElementById('basic-data').textContent = 
                `计数: ${state.count}, 消息: ${state.message}`
        }, { name: 'renderBasicData' })

        system.effect(() => {
            document.getElementById('user-data').textContent = 
                `姓名: ${state.user.name}, 年龄: ${state.user.age}, 等级: ${state.user.profile.level}`
        }, { name: 'renderUserData' })

        system.effect(() => {
            document.getElementById('computed-data').textContent = 
                `双倍计数: ${doubleCount.value}`
        }, { name: 'renderComputedData' })

        system.effect(() => {
            document.getElementById('array-data').textContent = 
                `列表长度: ${state.todos.length}, 第一个: ${state.todos[0]?.text || '无'}`
        }, { name: 'renderArrayData' })

        // 测试函数
        window.incrementCount = () => {
            state.count++
            system.log(`⬆️ 计数增加到: ${state.count}`)
        }

        window.updateUser = () => {
            state.user.name = state.user.name === '张三' ? '李四' : '张三'
            state.user.age++
            state.user.profile.points += 100
            system.log(`👤 更新用户信息`)
        }

        window.addTodo = () => {
            const newTodo = {
                id: Date.now(),
                text: `待办事项 ${state.todos.length + 1}`,
                completed: false
            }
            state.todos.push(newTodo)
            system.log(`✅ 添加待办: ${newTodo.text}`)
        }

        window.addNewProperty = () => {
            const newProp = `dynamic_${Date.now()}`
            state[newProp] = '动态添加的值'
            system.log(`➕ 添加新属性: ${newProp}`)
        }

        window.deleteProperty = () => {
            if (state.newProperty) {
                delete state.newProperty
                system.log(`➖ 删除属性: newProperty`)
            }
        }

        window.clearLogs = () => {
            document.getElementById('log-container').innerHTML = ''
            system.logs = []
            system.log('🧹 日志已清空')
        }

        system.log('🎉 Vue3 响应式系统演示已初始化完成')
    </script>
</body>
</html>

四、 响应式系统核心原理深度解析

4.1 依赖收集的详细过程

流程图:依赖收集详细流程

flowchart TD
    A[读取响应式属性] --> B[Proxy.get 拦截]
    B --> C[检查 activeEffect]
    C --> D{activeEffect 存在?}
    D -- 是 --> E[查找/创建 depsMap]
    D -- 否 --> F[直接返回值]
    
    E --> G[查找/创建 dep Set]
    G --> H[添加 effect 到 dep]
    H --> I[记录依赖关系]
    I --> J[返回属性值]
    
    F --> J

4.2 派发更新的详细过程

流程图:派发更新详细流程

flowchart TD
    A[修改响应式属性] --> B[Proxy.set 拦截]
    B --> C[值是否改变?]
    C -- 是 --> D[查找 depsMap]
    C -- 否 --> E[直接返回]
    
    D --> F{找到对应的 dep?}
    F -- 是 --> G[遍历 dep 中的 effects]
    F -- 否 --> E
    
    G --> H[执行调度器或直接执行]
    H --> I[effect 重新执行]
    I --> J[重新收集依赖]

4.3 嵌套依赖和清理机制

// 高级响应式特性实现
class AdvancedReactiveSystem extends ReactiveSystem {
  constructor() {
    super()
    this.effectStack = [] // 用于处理嵌套 effect
  }

  effect(fn, options = {}) {
    const effectFn = () => {
      // 清理之前的依赖
      this.cleanup(effectFn)
      
      // 推入 effect 栈
      this.effectStack.push(effectFn)
      this.activeEffect = effectFn
      
      try {
        return fn()
      } finally {
        // 弹出 effect 栈
        this.effectStack.pop()
        this.activeEffect = this.effectStack[this.effectStack.length - 1]
      }
    }
    
    effectFn.name = options.name || fn.name || 'anonymous'
    effectFn.scheduler = options.scheduler
    effectFn.deps = [] // 存储此 effect 依赖的所有 dep
    
    // 立即执行
    effectFn()
    
    return effectFn
  }

  cleanup(effectFn) {
    // 从所有依赖中移除此 effect
    for (const dep of effectFn.deps) {
      dep.delete(effectFn)
    }
    effectFn.deps.length = 0
  }

  track(target, key) {
    if (!this.activeEffect) return
    
    let depsMap = this.targetMap.get(target)
    if (!depsMap) {
      depsMap = new Map()
      this.targetMap.set(target, depsMap)
    }
    
    let dep = depsMap.get(key)
    if (!dep) {
      dep = new Set()
      depsMap.set(key, dep)
    }
    
    if (!dep.has(this.activeEffect)) {
      dep.add(this.activeEffect)
      // 同时让 effect 记住这个 dep,用于清理
      this.activeEffect.deps.push(dep)
    }
  }
}

五、 响应式 API 深度解析

5.1 ref 的实现原理

class RefImpl {
  constructor(value) {
    this._value = value
    this.dep = new Set()
    this.__v_isRef = true
  }

  get value() {
    // 依赖收集
    if (activeEffect) {
      trackEffects(this.dep)
    }
    return this._value
  }

  set value(newVal) {
    if (newVal !== this._value) {
      this._value = newVal
      // 触发更新
      triggerEffects(this.dep)
    }
  }
}

function ref(value) {
  return new RefImpl(value)
}

function trackEffects(dep) {
  if (activeEffect) {
    dep.add(activeEffect)
    activeEffect.deps.push(dep)
  }
}

function triggerEffects(dep) {
  for (const effect of dep) {
    if (effect.scheduler) {
      effect.scheduler()
    } else {
      effect()
    }
  }
}

5.2 computed 的实现原理

class ComputedRefImpl {
  constructor(getter) {
    this._getter = getter
    this._value = undefined
    this._dirty = true
    this.dep = new Set()
    this.effect = effect(getter, {
      lazy: true,
      scheduler: () => {
        if (!this._dirty) {
          this._dirty = true
          triggerEffects(this.dep)
        }
      }
    })
  }

  get value() {
    if (activeEffect) {
      trackEffects(this.dep)
    }
    
    if (this._dirty) {
      this._value = this.effect()
      this._dirty = false
    }
    
    return this._value
  }
}

function computed(getter) {
  return new ComputedRefImpl(getter)
}

5.3 watch 的实现原理

function watch(source, cb, options = {}) {
  let getter
  if (typeof source === 'function') {
    getter = source
  } else {
    getter = () => traverse(source)
  }
  
  let oldValue, newValue
  const job = () => {
    newValue = effectFn()
    cb(newValue, oldValue)
    oldValue = newValue
  }
  
  const effectFn = effect(
    () => getter(),
    {
      lazy: true,
      scheduler: job
    }
  )
  
  if (options.immediate) {
    job()
  } else {
    oldValue = effectFn()
  }
}

function traverse(value, seen = new Set()) {
  if (typeof value !== 'object' || value === null || seen.has(value)) {
    return value
  }
  seen.add(value)
  for (const key in value) {
    traverse(value[key], seen)
  }
  return value
}

六、 响应式系统性能优化

6.1 响应式系统性能对比

// 性能测试示例
function performanceTest() {
  const system = new ReactiveSystem()
  
  // 创建大型响应式对象
  const largeData = system.reactive(
    Array.from({ length: 1000 }, (_, i) => ({
      id: i,
      name: `Item ${i}`,
      value: Math.random(),
      nested: {
        level1: {
          level2: {
            data: `Nested ${i}`
          }
        }
      }
    }))
  )
  
  // 测试读取性能
  console.time('读取性能')
  system.effect(() => {
    let total = 0
    for (let i = 0; i < largeData.length; i++) {
      total += largeData[i].value
    }
    return total
  }, { name: 'performanceTest' })
  console.timeEnd('读取性能')
  
  // 测试更新性能
  console.time('更新性能')
  for (let i = 0; i < 100; i++) {
    largeData[i].value = Math.random()
  }
  console.timeEnd('更新性能')
}

// 运行性能测试
performanceTest()

6.2 优化技巧

// 1. 使用 shallowRef 避免深度响应式
function shallowRef(value) {
  return {
    _value: value,
    get value() {
      trackEffects(this.dep)
      return this._value
    },
    set value(newVal) {
      this._value = newVal
      triggerEffects(this.dep)
    }
  }
}

// 2. 使用 markRaw 标记非响应式对象
function markRaw(obj) {
  obj.__v_skip = true
  return obj
}

// 3. 合理使用 computed 缓存计算结果
const expensiveValue = computed(() => {
  // 复杂计算...
  return heavyCalculation()
})

七、 实际应用场景

7.1 组件状态管理

// 使用响应式系统实现简单的状态管理
class Store {
  constructor() {
    this.system = new ReactiveSystem()
    this.state = this.system.reactive({
      user: null,
      settings: {
        theme: 'light',
        language: 'zh-CN'
      },
      cart: []
    })
    
    this.getters = {
      cartTotal: this.system.computed(() => 
        this.state.cart.reduce((total, item) => total + item.price, 0)
      ),
      itemCount: this.system.computed(() => this.state.cart.length)
    }
    
    this.mutations = {
      setUser: (user) => { this.state.user = user },
      addToCart: (item) => { this.state.cart.push(item) },
      updateSettings: (settings) => { 
        Object.assign(this.state.settings, settings) 
      }
    }
  }
}

7.2 表单处理

// 响应式表单处理
function useForm(initialValues = {}) {
  const system = new ReactiveSystem()
  const form = system.reactive({ ...initialValues })
  const errors = system.reactive({})
  const touched = system.reactive({})
  
  const validate = system.computed(() => {
    const result = {}
    // 验证逻辑...
    return result
  })
  
  const isValid = system.computed(() => 
    Object.keys(validate.value).length === 0
  )
  
  return {
    form,
    errors,
    touched,
    validate,
    isValid
  }
}

八、 总结

8.1 Vue3 响应式系统的核心优势

  1. 更精确的依赖追踪:基于 Proxy 的全面拦截
  2. 更好的性能:惰性代理和按需响应
  3. 更完善的功能:支持 Map、Set、数组方法等
  4. 更好的开发体验:完整的 TypeScript 支持

8.2 响应式系统核心机制

  • 依赖收集:在 get 操作时建立属性与 effect 的映射
  • 派发更新:在 set 操作时通知相关 effect 重新执行
  • 清理机制:每次 effect 执行前清理旧依赖
  • 调度系统:支持异步更新和批量更新

8.3 性能优化要点

  1. 避免不必要的深度响应式:使用 shallowRef
  2. 合理使用计算属性:缓存复杂计算结果
  3. 注意内存泄漏:及时清理不需要的 effect
  4. 批量更新:使用 nextTick 合并多次更新

Vue3 的响应式系统通过精妙的设计,实现了高效、精确的数据变化追踪,为现代前端应用提供了强大的数据驱动能力。理解其工作原理对于编写高性能的 Vue 应用至关重要。


如果这篇文章对你有帮助,欢迎点赞、收藏和评论!有任何问题都可以在评论区讨论。在这里插入图片描述