vue2.x使用defineProperty重写get,set实现响应式,同时无法监听数组的变化,需要重写push、pop等方法。并且在初始化的时候遍历data,对每个数据进行处理,当data中的数据多,层级多时可能出现白屏的情况。
而vue3使用proxy实现响应式,本身就可以监听数组的变化,同时在get的时候 return reactive(result),使的只有在调用的时候才会进行处理,这样就不会出现在vue2中因数据太多而白屏的情况。并且除了get和set外,还能监听delete!
let data = {
selected: 1,
a: 'fff',
aa: {
c: 1,
d: 3
},
arr: [1,2,3,4]
}
let proxyData = reactive(data)
proxyData.a = 'ff'
proxyData.arr[0] = 5
console.log(proxyData.arr)
function reactive(target) {
if (typeof target !== 'object' || target === null) {
return
}
const proxyConfig = {
get (target, key, receiver) {
const ownKeys = Reflect.ownKeys(target)
if (ownKeys.includes(key)) {
// todo 监听
}
const result = Reflect.get(target, key, receiver)
return reactive(result)
},
set (target, key, value, receiver) {
if (value === target[key]) {
return
}
const ownKeys = Reflect.ownKeys(target)
if (ownKeys.includes(key)) {
// 已有数据
console.log('这是的数已有的数据')
} else {
// 新增数据
console.log('这是新增的数据')
}
const result = Reflect.set(target, key, value, receiver)
console.log('修改了值')
return result
},
deleteProperty (target, key) {
const result = Reflect.deleteProperty(target, key)
console.log('key => ', key)
console.log('target => ', target)
return result
}
}
return new Proxy(target, proxyConfig)
}