SOURCE

class Dep {
    constructor() {
        this.subs = []
    }

    addSub(sub) {
        this.subs.push(sub)
    }

    notify() {
        this.subs.forEach(sub => {
            sub.update()
        })
    }
}

class Watcher {
    constructor() {
        Dep.target = this
    }

    update() {
        console.log('视图更新')
    }
}

function defineReactive(obj, key, value) {
    const dep = new Dep()

    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function() {
            dep.addSub(Dep.target);
            return value;
        },
        set: function(newVal) {
            if (newVal === value) return;
            dep.notify();
        }
    })
}

function observer(value) {
    if (!value || typeof value !== 'object') return;
    Object.keys(value).forEach(key => {
        defineReactive(value, key, value[key])
    })
}

class Vue {
    constructor(options) {
        this._data = options.data;
        observer(this._data);
        new Watcher();
    }
}

let o = new Vue({
    data: {
        test: "123"
    }
})

o._data.test
o._data.test

o._data.test = "hello"
console 命令行工具 X clear

                    
>
console