手写vue响应式原理
<script>
//依赖
let Dep = (function() {
function Dep() {
this.deps = []; // 用来存储全部的依赖watcher
};
// 收集依赖
Dep.prototype.addDep = function (watcher) {
this.deps.push(watcher);
console.log("收集依赖的列表", this.deps);
};
// 通知依赖
Dep.prototype.notify = function(params) {
console.log('params', params)
this.deps.forEach(item => {
item.update(params); // 通过watch中的update,通知页面更新
});
};
return Dep;
})(); // 立即执行函数体
//属性全部的依赖就是watcher
let Watcher = (function() {
function Watcher(id) {
this.id = id;
};
Watcher.prototype.update = (value) => {
console.log("数据改变了,通知我要更新", value)
document.getElementById("text").innerText = value;
};
return Watcher;
})();
let obj = {
name: "nihao",
age: 18
};
let dep = new Dep(); // 新建用于存储watcher的数据
let value = obj.age;
// 响应式方法
Object.defineProperty(obj, "age", {
get() {
let watcher = new Watcher("1"); // 实例化一个watcher
console.log('watcher', watcher)
dep.addDep(watcher); // 收集依赖
return value; // return的值不能直接,会溢出
},
set(value) {
console.log('set调取')
dep.notify(value);
},
});
console.log(obj.age) // 读取age,会调取get方法
obj.age = 23; // 改变age,会调取set方法
document.getElementById("app").addEventListener("click", () => {
obj.age = (Math.random()*20).toFixed();
})
</script>