vue 响应式的原理和依赖收集与追踪

295 阅读1分钟
// new Avue({data:{}})
class Avue {
    constructor(options) {
            //对options进行缓存
            this.$options = options
                //对data也进行缓存
            this.$data = options.data;
            this.observer(this.$data);
            //模拟一个watcher();
            new watcher();
            this.$data.name;
            new watcher();
            this.$data.obj.age;
        }
        //进行数据得监听
    observer(value) {
        //如果没有值或者值得类型不是对象就直接return出去
        if (!value || typeof value !== "object") {
            return;
        }

        Object.keys(value).forEach(key => {
            this.defineReactive(value, key, value[key])
        })
    }

    defineReactive(obj, key, val) {
        //深度拷贝,使用递归,解决数据得层次嵌套
        this.observer(val)
        const dep = new Dep();
        //数据劫持
        Object.defineProperty(obj, key, {
            get() {
                //如果存在,就将添加到addDep ,这个属性必须是在读取得时候获得
                Dep.target && dep.addDep(Dep.target);
                return val
            },
            set(newVal) {
                if (newVal === val) return;
                val = newVal;
                // console.log(`${key}:更新了${val}`)
                //去通知dep
                dep.notify()
            }
        })
    }

}
//依赖收集和追踪
//DEP: 用来管理wacher
class Dep {
    constructor() {
            //存储所有得依赖
            this.deps = []
        }
        //在deps中添加一个监听器对象
    addDep(dep) {
            this.deps.push(dep)
        }
        //通知所有监听器去更新视图
    notify() {
        this.deps.forEach(dep => {
            dep.update()
        })
    }
}

class watcher {
    constructor() {
            //在new一个监听器对象时将该对象赋值给Dep.targte,在get中会用到
            //将当前watcher实例指定到Dep静态属性target
            console.log(Dep.target, this)
            Dep.target = this
        }
        //更新视图得方法
    update() {
        console.log("视图更新啦~~~")
    }
}

vue的响应原理:

创建一个自己vue的构造函数,里面observer是用来监听数据的,defineReactive用Object.defineProperty监听数据:

// new Avue({data:{}})
class Avue {
    constructor(options) {
            //对options进行缓存
            this.$options = options
                //对data也进行缓存
            this.$data = options.data;
            this.observer(this.$data);
        }
        //进行数据得监听
    observer(value) {
        //如果没有值或者值得类型不是对象就直接return出去
        if (!value || typeof value !== "object") {
            return;
        }
        Object.keys(value).forEach(key => {
            this.defineReactive(value, key, value[key])
        })
    }

    defineReactive(obj, key, val) {
        //深度拷贝,使用递归,解决数据得层次嵌套
        this.observer(val)
        //数据劫持
        Object.defineProperty(obj, key, {
            get() {
                return val
            },
            set(newVal) {
                if (newVal === val) return;
                val = newVal;
                 console.log(`${key}:更新了${val}`)
            }
        })
    }

}

依赖收集与收集:
有一个Dep构造函数用来管理watcher,而watcher是监听Dep静态属性;

//依赖收集和追踪
//DEP: 用来管理wacher
class Dep {
    constructor() {
            //存储所有得依赖
            this.deps = []
        }
        //在deps中添加一个监听器对象
    addDep(dep) {
            this.deps.push(dep)
        }
        //通知所有监听器去更新视图
    notify() {
        this.deps.forEach(dep => {
            dep.update()
        })
    }
}

class watcher {
    constructor() {
            //在new一个监听器对象时将该对象赋值给Dep.targte,在get中会用到
            //将当前watcher实例指定到Dep静态属性target
            Dep.target = this   //在读取属性的时候,在添加
        }
        //更新视图得方法
    update() {
        console.log("视图更新啦~~~")
    }
}

一开始的代码是两者的结合;