Vue3系列 - 响应式系统的核心:reactive和ref

2025 年 8 月 31 日 星期日(已编辑)
/
12

Vue3系列 - 响应式系统的核心:reactive和ref

响应式系统的核心:reactive和ref

Vue3的响应式系统是整个框架的核心,它通过reactiveref两个主要API实现数据的响应式处理。在Vue2.7中,这些API是基于Vue2的getter/setter实现的,而非Vue3中的Proxy。

reactive的实现原理

reactive函数用于将一个对象转换为响应式对象。让我们看看它的实现:

export function reactive(target) {
  makeReactive(target, false)
  return target
}

function makeReactive(target, shallow) {
  // 如果尝试观察一个只读代理,返回只读版本
  if (!isReadonly(target)) {
    // 开发环境下的警告...
    const ob = observe(
      target,
      shallow,
      isServerRendering()
    )
    // 更多检查和警告...
  }
}

这里的关键是observe函数,它是Vue2响应式系统的核心,会为对象创建一个Observer实例,通过Object.defineProperty为对象的每个属性定义getter和setter,从而实现依赖收集和变更通知。

与Vue3不同的是,Vue2.7中的reactive直接修改原始对象,而不是创建一个Proxy:

// 在Vue2.7中为true,在Vue3中为false
reactive(foo) === foo

ref的实现原理

ref函数用于创建一个包含单一值的响应式引用:

function createRef(rawValue, shallow) {
  if (isRef(rawValue)) {
    return rawValue
  }
  const ref = {}
  def(ref, RefFlag, true) // 标记为ref
  def(ref, ReactiveFlags.IS_SHALLOW, shallow)
  def(
    ref,
    'dep',
    defineReactive(ref, 'value', rawValue, null, shallow, isServerRendering())
  )
  return ref
}

ref创建了一个带有value属性的对象,通过defineReactive使这个属性变成响应式的。当我们访问或修改.value属性时,就会触发依赖收集或通知更新。

为什么需要ref?

在JavaScript中,原始类型(如数字、字符串)是按值传递的,无法通过对象属性的getter/setter追踪变化。ref通过将值包装在一个对象中,利用对象的响应式特性来追踪原始值的变化。

总结

Vue2.7中的响应式系统虽然基于Vue2的实现,但提供了与Vue3类似的API,使开发者可以逐步迁移到Vue3的编程风格。理解reactiveref的实现原理,有助于我们更好地使用Vue的响应式系统,避免常见的陷阱。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...