1. 程式人生 > >Vue原始碼學習(4)——資料響應系統

Vue原始碼學習(4)——資料響應系統

Vue原始碼學習(4)——資料響應系統:通過initData() 看資料響應系統

 

 

下面,根據理解我們寫一個簡略的原始碼:參考

治癒watcher在:vm.$mount(vm.$options.el) 

 

Function defineReactive(obj,key,val){
    Object.defineProperty(obj,key, {
        enumerable: true,
        configurable: true,
        get: function () {
            if (Dep. Target ) {
                dep. Depend ();  //收集依賴等同 dep.addSub(Dep.target)
            }
            return val;
        },
        set: function (newVal) {
         //判斷新值與舊值是否相等,判斷的後半段是為了驗證新值與舊值都為NaN的情況,NaN不等於自身
        if (newVal === val || (newVal !== newVal && value !== value)){
                return ;
            }
            val = newVal;
            dep. notify (); //釋出改變
        }
    });
}

 

class Dep {
    constructor(){
        this.subs = []; //訂閱的資訊
    }
    addSub(sub){
        this.subs.push(sub);
    }
    removeSub (sub) {
        remove(this.subs, sub);
    }
    
    depend() { //此方法的作用等同於 this.subs.push(Watcher);
        if (Dep.target) {
            Dep.target.addDep(this);
        }
    }
    
    notify () {//這個方法就是釋出通知了 告訴你 有改變啦
      const subs = this.subs.slice()
      for (let i = 0, l = subs.length; i < l; i++) { subs[i].update();   }
    }
}
Dep.target = null;

 

//低配的不能再低配的watcher物件
//(原始碼中是一個類,這用一個物件代替)
const watcher = {
    addDep:function (dep) {
        dep. addSub(this);
    },
    update: function() {
        html();
    }
}

//假裝這個是渲染頁面的
function html () {
document.querySelector('body')
.innerHTML = obj.html;
}

 

defineReactive(obj,'html','how are you');//定義響應式的資料

Dep.target = watcher;
html();//第一次渲染介面
Dep.target = null;

/*
瀏覽器測試:
首先,網頁內容為:'how are you'
然後,在控制檯輸入:
obj.html = 'I am fine thank you'
網頁內容變為:'I am fine thank you'
*/