手寫響應(yīng)式原理-vue3
let activeReactiveFn = null;
class Depend {
constructor() {
this.reactiveFns = new Set();
}
depend() {
if (activeReactiveFn) {
this.reactiveFns.add(activeReactiveFn);
}
}
notify() {
this.reactiveFns.forEach((fn) => fn());
}
}
const targetMap = new WeakMap();
const getDepend = (target, key) => {
let map = targetMap.get(target);
if (!map) {
map = new Map();
targetMap.set(target, map);
}
let depend = map.get(key);
if (!depend) {
depend = new Depend();
map.set(key, depend);
}
return depend;
};
const watchEffect = (fn) => {
activeReactiveFn = fn;
fn(); //執(zhí)行函數(shù)并收集依賴
activeReactiveFn = null;
};
//傳入一個(gè)普通對(duì)象,返回一個(gè)Proxy代理對(duì)象
const reactive = (obj) => {
return new Proxy(obj, {
//監(jiān)聽獲取對(duì)象的屬性值
get(target, key, receiver) {
const depend = getDepend(target, key);
depend.depend();
return Reflect.get(target, key, receiver);
},
//監(jiān)聽設(shè)置對(duì)象的屬性值
set(target, key, newVal, receiver) {
Reflect.set(target, key, newVal, receiver);
const depend = getDepend(target, key);
depend.notify();
},
});
};
const obj = reactive({
name: "why",
age: 18,
});
const info =reactive({
name: 'koby'
})
//收集每一個(gè)依賴obj.name的函數(shù)
watchEffect(() => {
const newName = obj.name;
console.log(newName);
});
watchEffect(() => {
console.log(obj.name);
console.log(obj.age);
});
watchEffect(() => {
console.log(obj.age);
});
watchEffect(() => {
console.log(info.name);
});
//當(dāng)obj.name的值發(fā)生改變,所有包含依賴obj.name的代碼塊的函數(shù)都重新執(zhí)行
obj.name = "lily";
手寫響應(yīng)式原理-vue2
let activeReactiveFn = null;
class Depend {
constructor() {
this.reactiveFns = new Set();
}
depend() {
if (activeReactiveFn) {
this.reactiveFns.add(activeReactiveFn);
}
}
notify() {
this.reactiveFns.forEach((fn) => fn());
}
}
const targetMap = new WeakMap();
const getDepend = (target, key) => {
let map = targetMap.get(target);
if (!map) {
map = new Map();
targetMap.set(target, map);
}
let depend = map.get(key);
if (!depend) {
depend = new Depend();
map.set(key, depend);
}
return depend;
};
const watchEffect = (fn) => {
activeReactiveFn = fn;
fn(); //執(zhí)行函數(shù)并收集依賴
activeReactiveFn = null;
};
//傳入一個(gè)普通對(duì)象,返回一個(gè)Proxy代理對(duì)象
const reactive = (obj) => {
Object.keys(obj).forEach((key) => {
const value = obj[key];
Object.defineProperty(obj, key, {
get() {
const depend = getDepend(obj, key);
depend.depend();
return value;
},
set(newVal) {
value = newVal;
const depend = getDepend(obj, key);
depend.notify();
},
});
});
return obj;
};
const obj = reactive({
name: "why",
age: 18,
});
const info = reactive({
name: "koby",
});
//收集每一個(gè)依賴obj.name的函數(shù)
watchEffect(() => {
const newName = obj.name;
console.log(newName);
});
watchEffect(() => {
console.log(obj.name);
console.log(obj.age);
});
watchEffect(() => {
console.log(obj.age);
});
watchEffect(() => {
console.log(info.name);
});
//當(dāng)obj.name的值發(fā)生改變,所有包含依賴obj.name的代碼塊的函數(shù)都重新執(zhí)行
obj.name = "lily";
非常感謝王紅元老師的深入JavaScript高級(jí)語法讓我學(xué)習(xí)到很多 JavaScript 的知識(shí)