全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-20 7 分钟 ✍️ juanwangdev

响应式原理

Vue 的核心特性之一是响应式系统,当数据变化时视图会自动更新。

Vue 2: Object.defineProperty

Vue 2 使用 Object.defineProperty 将对象属性转换为 getter/setter:

JavaScript
function defineReactive(obj, key, val) {
  const dep = new Dep()
  Object.defineProperty(obj, key, {
    get() {
      if (Dep.target) dep.depend()
      return val
    },
    set(newVal) {
      if (newVal !== val) {
        val = newVal
        dep.notify()
      }
    }
  })
}

局限性

  • 无法检测对象属性的添加或删除
  • 无法检测数组索引的直接赋值
  • 需要使用 Vue.set / vm.$set 手动处理
JavaScript
// 正确做法
this.$set(this.user, 'age', 25)
this.$set(this.arr, 0, 'new value')

Vue 3: Proxy

Vue 3 使用 Proxy 重写响应式系统:

JavaScript
function reactive(target) {
  return new Proxy(target, {
    get(target, key, receiver) {
      const res = Reflect.get(target, key, receiver)
      track(target, key)
      return typeof res === 'object' ? reactive(res) : res
    },
    set(target, key, value, receiver) {
      const res = Reflect.set(target, key, value, receiver)
      trigger(target, key)
      return res
    }
  })
}

Proxy 的优势

  • 可拦截 13 种操作,包括属性添加/删除
  • 原生支持数组索引修改
  • 惰性响应,嵌套对象按需代理
JavaScript
const state = reactive({ count: 0 })
state.count++ // 自动触发更新
state.newKey = 'hello' // Vue 3 可检测,Vue 2 不行

ref 与 reactive

JavaScript
import { ref, reactive } from 'vue'

// ref 用于基本类型
const count = ref(0)
count.value++

// reactive 用于对象
const state = reactive({ count: 0 })
state.count++

要点总结

  • Vue 2 使用 Object.defineProperty,存在数组和动态属性检测盲区
  • Vue 3 使用 Proxy,能力更强,性能更好
  • ref 包装基本类型,reactive 处理对象
  • 响应式是 Vue 自动更新视图的基础

📝 发现内容有误?点击此处直接编辑

← 上一篇 依赖收集与触发
下一篇 → 异步更新队列
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库