vue响应式原理

129 阅读1分钟
        // Watcher 即观察者,观察数据,数据变化时更新对应的视图(dom)。
        // Observer 即劫持者,通过 Object.defineProperty 给数据设置 get 和 set 方法
        class MyVue {
            constructor(options) {
                this._data = options.data;
                this.observer(this._data)
                debugger
                new Watcher();
            }
            observer(obj) {
                if (!obj || (typeof obj !== 'object')) {
                    return;
                }
                Object.keys(obj).forEach((key) => {
                    this.defineReactive(obj, key, obj[key])
                })
            }
            defineReactive(obj, key, val) {
                let that = this
                const dep = new Dep();
                Object.defineProperty(obj, key, {
                    enumerable: true,
                    configurable: true,
                    get: function () {
                        dep.addSub(Dep.target)
                        console.log('getter')
                        return val
                    },
                    set: function (newval) {
                        if (val == newval) {
                            return
                        }
                        console.log(newval)
                        dep.notify();

                    }
                })
            }
            draw(val) {
                console.log('draw')
            }
        }
        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('update')
            }
        }
        let myVue = new MyVue({
            data: {
                test1: 'I am test',
                test2: 'hhhhh'
            }
        });
        console.log(myVue._data.test1)
        console.log(myVue._data.test2)
        myVue._data.test = "hello,world.";