SOURCE

/*
* 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 命令行工具 X clear

                    
>
console