Vue的实现原理 proxy
Vue 3 的 Proxy 实现原理
Vue 3 使用 Proxy 替代 Vue 2 中的 Object.defineProperty 来实现响应式系统。Proxy 是 ES6 提供的原生对象,能够拦截对目标对象的操作,从而实现更强大的响应式能力。
Proxy 的基本概念
Proxy 可以创建一个对象的代理,拦截并重新定义对象的基本操作。例如属性读取、设置、删除等。Proxy 的构造函数接受两个参数:
- target:要代理的目标对象
- handler:包含拦截操作的对象
const proxy = new Proxy(target, handler)
Vue 3 的响应式实现
Vue 3 的响应式系统主要通过以下步骤实现:
- 创建响应式对象
Vue 使用
reactive()函数创建响应式对象,内部使用 Proxy 进行包装。
function reactive(target) {
return new Proxy(target, {
get(target, key, receiver) {
track(target, key) // 依赖收集
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver)
trigger(target, key) // 触发更新
return result
}
})
}
- 依赖收集与触发更新
Vue 3 使用
track和trigger函数来管理依赖关系。
track:在 get 操作时收集当前正在运行的 effect(副作用函数)trigger:在 set 操作时触发所有相关的 effect 重新执行
- Effect 系统
Vue 3 的
effect函数用于创建响应式副作用,类似于 Vue 2 的 Watcher。
let activeEffect
function effect(fn) {
activeEffect = fn
fn()
activeEffect = null
}
Proxy 相比 Object.defineProperty 的优势
-
可以检测到对象属性的添加和删除 Object.defineProperty 无法检测到新增或删除的属性,而 Proxy 可以。

-
支持数组的响应式 Proxy 可以直接拦截数组的操作(push、pop 等),无需特殊处理。
-
性能更好 Proxy 是语言层面的实现,比 Object.defineProperty 的遍历属性方式更高效。
-
支持嵌套对象 Proxy 可以递归代理嵌套对象,实现深层响应式。

响应式系统的局限性
-
原始值需要 ref 包装 对于原始值(number、string 等),需要使用
ref()进行包装。 -
解构可能丢失响应性 直接解构响应式对象可能导致属性失去响应性,需要使用
toRefs。 -
浏览器兼容性 Proxy 无法被 polyfill,在旧版浏览器中无法使用。
实际应用示例
import { reactive, effect } from 'vue'
const state = reactive({
count: 0
})
effect(() => {
console.log('count changed:', state.count)
})
state.count++ // 触发 effect 执行
总结
Vue 3 使用 Proxy 实现的响应式系统更加灵活和高效,解决了 Vue 2 中的诸多限制。通过 Proxy 的拦截能力,Vue 能够精确地追踪依赖关系,并在数据变化时高效地更新视图。






