vue数据代理底层实现
Vue数据代理的底层实现原理
Vue的数据代理是通过Object.defineProperty或Proxy实现的,主要目的是让开发者能够直接通过实例访问data中的属性,而不需要写data.xxx的形式。
基于Object.defineProperty的实现
在Vue 2.x版本中,数据代理主要依赖Object.defineProperty:
function observe(data) {
if (!data || typeof data !== 'object') return
Object.keys(data).forEach(key => {
defineReactive(data, key, data[key])
})
}
function defineReactive(obj, key, val) {
observe(val) // 递归处理嵌套对象
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get() {
return val
},
set(newVal) {
if (newVal === val) return
val = newVal
// 触发更新
}
})
}
基于Proxy的实现
Vue 3.x改用Proxy实现数据代理:
function reactive(target) {
const handler = {
get(target, key, receiver) {
const result = Reflect.get(target, key, receiver)
if (typeof result === 'object') {
return reactive(result) // 深层代理
}
return result
},
set(target, key, value, receiver) {
const oldValue = target[key]
const result = Reflect.set(target, key, value, receiver)
if (oldValue !== value) {
// 触发更新
}
return result
}
}
return new Proxy(target, handler)
}
数据代理的核心流程
初始化阶段遍历data对象的所有属性 通过Object.defineProperty或Proxy将这些属性代理到Vue实例上 访问实例属性时实际上访问的是data对象对应属性 修改实例属性时会同步修改data对象对应属性
与响应式系统的关系
数据代理与响应式系统紧密相关 属性访问会收集依赖 属性修改会触发依赖更新 代理机制使得模板可以直接访问data属性
性能优化考虑
Vue 3改用Proxy主要因为: 可以直接监听数组变化 性能更好 能拦截更多操作类型 支持深层监听无需递归
对于大型对象,Proxy的性能优势更明显







