Vue 3 响应式系统深度解析

一、前言

Vue 3 的核心之一是响应式系统(Reactivity System),它是整个框架的"感官神经",负责追踪数据变化并触发视图更新。相比 Vue 2 的 Object.defineProperty 实现方式,Vue 3 完全重构为基于 Proxy 的新架构,不仅性能更高,也让响应式逻辑更灵活。


二、响应式的基础概念

Vue 3 响应式系统主要由以下几个部分组成:

  • reactive():将对象转为响应式对象。
  • ref():为基本类型(如字符串、数字)创建响应式引用。
  • computed():创建基于依赖的惰性求值属性。
  • effect():注册副作用函数(响应式追踪的核心机制)。
import { reactive, effect } from 'vue'

const state = reactive({ count: 0 })

effect(() => {
  console.log(`count 值为: ${state.count}`)
})

state.count++  // 会触发 effect 再次执行

三、依赖收集与触发更新

响应式的实现核心是 依赖收集 (Dependency Tracking) 与 **触发更新 (Triggering Effects)**。

  1. 依赖收集:
    当某个响应式对象的属性在 effect 内被访问时,Vue 会记录该属性与副作用函数的对应关系。
  2. 触发更新:
    当该属性被修改时,系统会重新执行所有依赖它的副作用函数,从而更新视图或计算属性。

这种机制让 Vue 能自动感知"谁依赖了谁",实现精准更新。


四、Reactive 的底层实现原理

Vue 3 的响应式实现核心文件在源码中位于 packages/reactivity/
其核心逻辑基于 Proxy 拦截对象的 getset 操作。

const targetMap = new WeakMap()

function reactive(target) {
  return new Proxy(target, {
    get(obj, key) {
      track(obj, key)
      return Reflect.get(obj, key)
    },
    set(obj, key, value) {
      const result = Reflect.set(obj, key, value)
      trigger(obj, key)
      return result
    }
  })
}

function track(target, key) {
  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)
}

function trigger(target, key) {
  const depsMap = targetMap.get(target)
  const deps = depsMap?.get(key)
  deps && deps.forEach(fn => fn())
}

五、Ref 与 Reactive 的区别

特性 reactive ref


适用类型 对象 基本类型 是否可解构 否 是 内部实现 Proxy 对象包装 { value: xxx }

const count = ref(0)
watchEffect(() => {
  console.log(count.value)
})
count.value++

ref 的设计让基本类型也能具备响应性,统一了 Vue 的响应式体系。


六、响应式的优化机制

Vue 3 引入了多个优化机制:

  1. 懒执行 (Lazy Evaluation) --- computed 只有在依赖变化时才会重新计算。\
  2. 依赖层级追踪 (Fine-grained Dependency Tracking) --- 精确追踪访问属性,减少无效更新。\
  3. 批量更新 (Scheduler) --- 多个依赖变化会被合并到同一个刷新周期中执行。

七、总结

Vue 3 的响应式系统是一种设计优雅、性能卓越的响应式编程模型:

  • 利用 Proxy 实现更精细的依赖追踪\
  • 拆分核心模块(effect、track、trigger)可独立复用\
  • 对外暴露 reactivity 包,允许开发者在非 Vue 环境中直接使用

掌握 Vue 3 的响应式机制,不仅能理解框架底层的"灵魂",也能在实际开发中写出更高效、可维护的代码。