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創建一個代理對象,是針對對象的監聽,無論是修改已有屬性,還是新增屬性都可以監聽到