// 存储副作用函数的集合,类似数组,但无序,比数组性能更好 const fns = new Set(); function reactive(obj) { return new Proxy(obj, { get(target, key) { // 取值时,若发现副作用函数,则添加到副作用函数集合 if (activeFn) fns.add(activeFn); const val = target[key]; if (typeof val === "object" && val != null) { // 若obj的属性值是对象,则递归 (此处仅考虑了属性值是对象的情况) return reactive(val); } else { return val; } }, set(target, key, newVal) { target[key] = newVal; // 更新值时,遍历执行一次所有副作用函数 fns.forEach((fn) => fn()); return true; }, }); } // ref 的本质,就是属性为 value 的对象的 reactive function ref(value) { return reactive({ value: value }); } let activeFn; function watchEffect(fn) { activeFn = fn; // 在创建时,即执行第一次回调 fn(); }
测试
const user = reactive({ name: "朝阳" }); watchEffect(() => { console.log("name", user.name); }); user.name = "张三"; setTimeout(() => { user.name = "李四"; }, 1000);