let activeReactiveFn = null
// 用来收集依赖
class Depend {
constructor () {
/**
* 使用数组的话使用下面的写法会导致函数触发三次, 其实只要触发一次即可
* watchFn(function () {
console.log('我触发了name1', objProxy.name);
console.log('我触发了name1', objProxy.name);
console.log('我触发了name1', objProxy.name);
})
*/
this.dependFns = new Set()
}
depend() {
if (activeReactiveFn) {
this.dependFns.add(activeReactiveFn)
}
}
notify() {
this.dependFns.forEach(fn => fn())
}
}
// 用来监听对象值发生改变时需要触发的函数
function watchFn(fn) {
activeReactiveFn = fn
fn();
activeReactiveFn = null
}
// 获取对象内的属性依赖
const targetMap = new WeakMap()
function 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 obj = {
name: 'why',
age: 18
}
const objProxy = new Proxy(obj, {
get(target, key, receiver) {
const depend = getDepend(target, key);
depend.depend()
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
const depend = getDepend(target, key);
depend.notify();
Reflect.set(target, key, newValue, receiver)
}
})
watchFn(function () {
console.log('我触发了name1', objProxy.name);
console.log('我触发了name1', objProxy.name);
console.log('我触发了name1', objProxy.name);
})
setTimeout(() => {
objProxy.name = 1;
}, 1000);
// 对上方代码进行封装, 因为可能有多个对象需要响应式
// 封装reactive
function reactive (obj) {
return new Proxy(obj, {
get(target, key, receiver) {
const depend = getDepend(target, key);
depend.depend()
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
const depend = getDepend(target, key);
depend.notify();
Reflect.set(target, key, newValue, receiver)
}
})
}
let activeReactiveFn = null
// 用来收集依赖
class Depend {
constructor () {
/**
* 使用数组的话使用下面的写法会导致函数触发三次, 其实只要触发一次即可
* watchFn(function () {
console.log('我触发了name1', objProxy.name);
console.log('我触发了name1', objProxy.name);
console.log('我触发了name1', objProxy.name);
})
*/
this.dependFns = new Set()
}
depend() {
if (activeReactiveFn) {
this.dependFns.add(activeReactiveFn)
}
}
notify() {
this.dependFns.forEach(fn => fn())
}
}
// 用来监听对象值发生改变时需要触发的函数
function watchFn(fn) {
activeReactiveFn = fn
fn();
activeReactiveFn = null
}
// 获取对象内的属性依赖
const targetMap = new WeakMap()
function 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 objProxy = reactive({
name: 'why',
age: 18
})
setTimeout(() => {
objProxy.name = 1;
}, 1000);
watchFn(function () {
console.log('我触发了name1', objProxy.name);
console.log('我触发了name1', objProxy.name);
console.log('我触发了name1', objProxy.name);
})
const fooProxy = reactive({
address: '福建省',
age: 18
})
setTimeout(() => {
fooProxy.address = 1;
}, 1000);
watchFn(function () {
console.log('我触发了address1', fooProxy.address);
console.log('我触发了address1', fooProxy.address);
console.log('我触发了address1', fooProxy.address);
})