vue3源码里reactive
方法简单实现
1、 源码
const toProxy = new WeakMap(); // 存放代理后的对象
const toRaw = new WeakMap(); // 存放代理前的对象
function isObject(target){
return typeof target === 'object' && target !== null;
}
function trigger(){
console.log('触发视图更新');
}
function reactive(target){
if(!isObject(target)){
return target;
}
// 如果代理表中已经存在,返回代理
if(toProxy.get(target)){
return toProxy.get(target);
}
// 如果这个对象已经被代理,返回这个对象
if(toRaw.get(target)){
return target;
}
let handlers = {
set(target, key, value, receiver){ // 设置值的时候触发
// 如果触发的是私有属性的话就触发更新
if(target.hasOwnProperty(key)){
trigger();
}
return Reflect.set(target, key, value, receiver);
},
get(target, key, receiver){ // 获取值的时候触发
const res = Reflect.get(target, key, receiver);
if(isObject(target[key])){
return receiver(res);
}
return res;
},
deleteProperty(target, key){ // 删除值的时候触发
return Reflect.deleteProperty(target, key);
}
}
let observed = new Proxy(target, handlers);
toProxy.set(target, observed);
toRgba.set(observed, target);
return observed;
}
let obj = {
name: 'cat',
array: [1,2,3]
}
let p = reactive(obj);
p.name = 'said';
console.log(obj);