Vue的实现原理 proxy
Vue 3 的响应式原理:Proxy
Vue 3 使用 Proxy 替代了 Vue 2 中的 Object.defineProperty 来实现响应式系统。Proxy 是 ES6 提供的一种机制,可以拦截对象的操作,如属性读取、赋值、删除等。
const reactive = (target) => {
return new Proxy(target, {
get(target, key, receiver) {
track(target, key) // 依赖收集
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
Reflect.set(target, key, value, receiver)
trigger(target, key) // 触发更新
return true
}
})
}
Proxy 的优势
- 深层监听:
Proxy可以监听对象的所有属性,包括新增和删除的属性,无需像Object.defineProperty那样递归遍历。 - 数组支持:
Proxy可以直接监听数组的变化(如push、pop等操作),而Object.defineProperty需要特殊处理。 - 性能更好:
Proxy只在访问属性时触发,而Object.defineProperty需要在初始化时递归遍历所有属性。
依赖收集与触发更新
Vue 3 的响应式系统通过 track 和 trigger 实现依赖收集和更新触发:
track:在读取属性时记录当前正在运行的副作用(如组件的渲染函数)。trigger:在属性修改时找到所有依赖该属性的副作用并重新执行。
let activeEffect = null
const track = (target, key) => {
if (activeEffect) {
// 将 activeEffect 添加到依赖集合中
}
}
const trigger = (target, key) => {
// 找到依赖 target[key] 的所有副作用并执行
}
与 Vue 2 的对比
- 初始化性能:Vue 2 的
Object.defineProperty需要在初始化时递归遍历所有属性,而 Vue 3 的Proxy是惰性的,仅在访问时处理。 - 动态属性:Vue 2 无法检测新增或删除的属性,而 Vue 3 可以。
- 数组监听:Vue 2 需要重写数组方法(如
push、pop),而 Vue 3 直接支持。
局限性
- 浏览器兼容性:
Proxy无法被 polyfill,因此 Vue 3 无法支持 IE11 及以下浏览器。 - 原始值限制:
Proxy只能代理对象,无法直接代理原始值(如字符串、数字),需通过ref包装。
总结
Vue 3 的 Proxy 实现了更高效、更灵活的响应式系统,解决了 Vue 2 中的许多限制,但需注意浏览器兼容性问题。







