1.vue2中响应式原理是Object.defineProperty
const obj = {
a: 1,
b: 2,
c: {
aa: 3
}
}
// vue2 Object.defineProperty
function isObject(value) {
return Object.prototype.toString.call(value) === '[object Object]'
}
function observeObj(obj) {
for (const k in obj) {
let v = obj[k]
if (isObject(v)) {
observeObj(v)
} else {
Object.defineProperty(obj, k, {
get() {
console.log('读取', k)
return v
},
set(val) {
console.log('赋值', k)
v = val
}
})
}
}
}
observeObj(obj)
console.log(obj.a)
obj.c.aa = 5
缺点:
1.Object.defineProperty是针对属性的监听,每次读写属性,都要遍历整个obj对象,监听其中每个属性的变化,性能不友好
2.由于是监听属性,所以只能监听到已有属性的变化,无法监听新增属性
3.无法监控到数组下标的变化,通过数组下标修改元素,无法实时响应
2.vue3响应式原理proxy
const obj = {
a: 1,
b: 2,
c: {
aa: 3
}
}
// vue3 Proxy
function isObject(value) {
return Object.prototype.toString.call(value) === '[object Object]'
}
function reactive(obj) {
const proxy = new Proxy(obj, {
get(target, k) {
console.log('读取', k)
if (isObject(target[k])) {
return reactive(target[k])
}
return target[k]
},
set(target, k, value) {
if (target[k] === value) {
return false
}
console.log('赋值', k)
target[k] = value
return true
}
})
return proxy
}
const proxy = reactive(obj)
// console.log(proxy.a)
proxy.c.aa = 5
通过proxy创建一个代理对象,是针对对象的监听,无论是修改已有属性,还是新增属性都可以监听到