vue怎么实现数据检测
Vue 数据检测实现方式
Vue 通过数据劫持和发布-订阅模式实现数据检测,核心机制基于 Object.defineProperty(Vue 2)或 Proxy(Vue 3)。以下是具体实现方法:
Vue 2 实现方案
使用 Object.defineProperty 递归劫持对象属性,为每个属性添加 getter/setter:

function observe(data) {
if (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, {
get() {
console.log('读取属性', key)
return val
},
set(newVal) {
if (newVal === val) return
console.log('更新属性', key)
observe(newVal) // 新值是对象时继续劫持
val = newVal
}
})
}
Vue 3 实现方案
使用 Proxy 代理整个对象,无需递归初始化:
function reactive(target) {
return new Proxy(target, {
get(target, key, receiver) {
console.log('读取属性', key)
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
console.log('更新属性', key)
return Reflect.set(target, key, value, receiver)
}
})
}
数组检测处理
Vue 2 对数组方法进行特殊处理:

const arrayProto = Array.prototype
const arrayMethods = Object.create(arrayProto)
const methodsToPatch = ['push', 'pop', 'shift', 'unshift', 'splice']
methodsToPatch.forEach(method => {
arrayMethods[method] = function(...args) {
const result = arrayProto[method].apply(this, args)
console.log('数组变更', method)
return result
}
})
依赖收集实现
通过 Dep 类和 Watcher 类建立依赖关系:
class Dep {
constructor() {
this.subs = new Set()
}
depend() {
if (currentWatcher) this.subs.add(currentWatcher)
}
notify() {
this.subs.forEach(watcher => watcher.update())
}
}
let currentWatcher = null
class Watcher {
constructor(fn) {
currentWatcher = this
fn()
currentWatcher = null
}
update() {
console.log('数据更新触发重新计算')
}
}
实际应用示例
组合以上机制实现响应式系统:
const data = { count: 1, list: [1, 2, 3] }
observe(data) // Vue 2 方式
// 或 const state = reactive(data) // Vue 3 方式
new Watcher(() => {
console.log('计算结果:', data.count * 2)
})
data.count = 2 // 触发更新通知
data.list.push(4) // 数组变更检测
Vue 的数据检测系统通过以上机制实现自动依赖跟踪和更新触发,开发者只需修改数据即可自动触发视图更新。






