function observer (value) {
if (!value || (typeof value !== 'object')) {
return;
}
Object.keys(value).forEach((key) => {
defineReactive(value, key, value[key]);
});
}
class Dep {
constructor () {
this.subs = [];
}
addSub (sub) {
this.subs.push(sub);
}
notify (newVal) {
this.subs.forEach((sub) => {
sub.update(newVal);
})
}
}
class Watcher {
vue
constructor (vue) {
Dep.target = this;
this.vue = vue
}
update (newVal) {
console.log(this.vue.data.key + " 的视图更新啦~", newVal);
}
}
function defineReactive (obj, key, val) {
const dep = new Dep();
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
dep.addSub(Dep.target);
return val;
},
set: function reactiveSetter (newVal) {
if (newVal === val) return;
dep.notify(newVal);
}
});
}
class Vue {
constructor(options) {
this.data = options.data;
observer(this.data);
new Watcher(this);
console.log('render~', this.data.name);
}
}
let v1 = new Vue({
data: {
key: 'v1',
name: "I am zy.",
age: 22
}
});
let v2 = new Vue({
data: {
key: 'v2',
name: "I am zy2.",
age: 33
}
});
v1.data.name = "ma1";
v2.data.name = "ma2";
console