vue 響應式的原理和依賴收集與追蹤

// 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

建立一個本身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靜態屬性;bash

//依賴收集和追蹤
//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("視圖更新啦~~~")
    }
}
複製代碼

一開始的代碼是二者的結合;函數

相關文章
相關標籤/搜索