/*
* vue 响应式原理 简版
**/
function observer (value) {
if (!value || (typeof value !== 'object')) {
return;
}
Object.keys(value).forEach((key) => {
defineReactive(value, key, value[key]);
});
}
class Dep {
constructor () {
/* 用来存放 Watcher 对象的数组 */
this.subs = [];
}
/* 在 subs 中添加一个 Watcher 对象 */
addSub (sub) {
this.subs.push(sub);
}
/* 通知所有 Watcher 对象更新视图 */
notify (newVal) {
this.subs.forEach((sub) => {
sub.update(newVal);
})
}
}
class Watcher {
vue
constructor (vue) {
/* 在 new 一个 Watcher 对象时将该对象赋值给 Dep.target,在 get 中会用到 */
Dep.target = this;
this.vue = vue
}
/* 更新视图的方法 */
update (newVal) {
console.log(this.vue.data.key + " 的视图更新啦~", newVal);
}
}
function defineReactive (obj, key, val) {
/* 一个 Dep 类对象 */
const dep = new Dep();
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
/* 将 Dep.target(即当前的 Watcher 对象存入 dep 的 subs 中) */
dep.addSub(Dep.target);
return val;
},
set: function reactiveSetter (newVal) {
if (newVal === val) return;
/* 在 set 的时候触发 dep 的 notify 来通知所有的 Watcher 对象更新视图 */
dep.notify(newVal);
}
});
}
class Vue {
constructor(options) {
this.data = options.data;
observer(this.data);
/* 新建一个 Watcher 观察者对象,这时候 Dep.target 会指向这个 Watcher 对象 */
new Watcher(this);
/* 在这里模拟 render 的过程,为了触发 test 属性的 get 函数 */
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
}
});
//console.log(v1.data.name)
v1.data.name = "ma1";
v2.data.name = "ma2";
console