Vue2使用defineProperty
//vue2 reacitve
let savefnNull = null;
let yui = {
name:"yui",
age:16
}
class Depend{
constructor(){
this.Setfn = new Set()
}
adddepend(){
if(savefnNull){
this.Setfn.add(savefnNull)
}
}
notify(){
this.Setfn.forEach(element => {
element()
});
}
}
const WMapobj = new WeakMap();
function SaveObj(target,key){
let Mapobj = WMapobj.get(target);
if(!Mapobj){
Mapobj = new Map()
WMapobj.set(target,Mapobj)
}
let objfn = Mapobj.get(key)
if(!objfn){
objfn = new Depend()
Mapobj.set(key,objfn)
}
return objfn;
}
function WatchFn(fn){
savefnNull = fn;
fn();
savefnNull = null;
}
function defineP (obj){
Object.keys(obj).forEach(key => {
let value = obj[key]
Object.defineProperty(obj,key,{
get: function(){
let depend = SaveObj(obj,key);
depend.adddepend();
return value;
},
set: function(newvalue){
value = newvalue;
let depend = SaveObj(obj,key)
console.log('sett-----------------')
depend.notify()
}
})
})
return obj;
}
let proxyyui = defineP(yui);
WatchFn(()=>{
console.log(proxyyui.name)
console.log('2'+proxyyui.name)
})
proxyyui.name = 'ss'
WatchFn(()=>{
console.log(proxyyui.age)
console.log('2'+proxyyui.age)
})
proxyyui.age = 15
Vue3使用Proxy
//Weakmap👉map👉{fn}
let SaveWatchFn = null
//用类存储方法
class Depend{
constructor(){
this.dependfn = new Set()
}
// adddepend(fn){
// this.dependfn.add(fn)
// }
depend(){
if(SaveWatchFn){
this.dependfn.add(SaveWatchFn)
}
}
notify(){
this.dependfn.forEach(element => {
element()
});
}
}
//在get调用时存入依赖方法
function WatchFn(fn){
SaveWatchFn = fn ;
fn() ;
SaveWatchFn = null ;
}
//收集响应式
let WatchWeakMap = new WeakMap()
function SaveProxyMap(target,key){
let objmap = WatchWeakMap.get(target)
if(!objmap){
objmap = new Map()
WatchWeakMap.set(target,objmap)
}
let KeyDependFn = objmap.get(key)
if(!KeyDependFn){
KeyDependFn = new Depend()
objmap.set(key,KeyDependFn)
}
return KeyDependFn
}
let yui = {
name:"yui",
age:16
}
function reacitve(obj){
return new Proxy(obj,{
get: function (target,key,receiver) {
let keyDepenfn = SaveProxyMap(target,key)
keyDepenfn.depend()
return Reflect.get(target,key,receiver)
},
set: function (target,key,newvalue,receiver) {
//先代理改变再执行响应方法
Reflect.set(target,key,newvalue,receiver)
console.log('set---------------------------')
let keyDepenfn = SaveProxyMap(target,key)
keyDepenfn.notify()
}
})
}
let yuiproxy = reacitve(yui)
WatchFn(function (){
console.log(yuiproxy.name)
})
WatchFn(function (){
console.log('name改变'+ yuiproxy.name)
})
WatchFn(function (){
console.log(yuiproxy.age)
})
WatchFn(function (){
console.log('age改变'+ yuiproxy.age)
console.log('age改变'+ yuiproxy.age)
})
yuiproxy.age = 1