重讀vue的MVVM

vue雙向數據綁定vue

watcher怎麼連接observe和compile?express

observe

* a.經過Object.defineProperty屬性拿到數據的getter和setter方法;[存取器]。
對象的屬性有任何賦值都會促發get方法。 發出一個消息, 訂閱這個消息訂閱者促發回掉;
* b.爲全部數據添加監聽器dep。

getter方法的時候,判斷存不存在dep.target,若是存在,就將dep.target添加到dep.addsub;
setter方法的時候,調用dep.notify(),遍歷dep裏面的訂閱者,而且執行update方法; 消息訂閱器bash

export default class Dep {
        constructor() {
            this.subs = [];
        };
        addSub(sub) {
            this.subs.push(sub);
        };
        notify() {
            this.subs.forEach(sub => sub.update());
        }
}
複製代碼

watch:

Dep.target = this; // 將當前訂閱者指向本身
var value = this.vm[exp]; //
觸發getter,添加本身到屬性訂閱器中
Dep.target = null; // 添加完畢,重置
return value; 代碼:
export default class Watcher {
    constructor(vm, expOrFn, cb) {
        this.cb = cb
        this.vm = vm
            //此處簡化.要區分fuction仍是expression,只考慮最簡單的expression
        this.expOrFn = expOrFn
        this.value = this.get()
    }
    update() {
        this.run()
    }
    run() {
        const value = this.get()
        if (value !== this.value) {
            this.value = value
            this.cb.call(this.vm)
        }
    }
    get() {
        Dep.target = this
            //此處簡化。。要區分fuction仍是expression
        const value = this.vm._data[this.expOrFn]
        Dep.target = null
        return value
    }
}
複製代碼

compile

主要作的事情是解析模板指令,將模板中的變量替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,更新視圖,如圖所示:

監聽數據、綁定更新函數的處理是在compileUtil.bind()這個方法中,經過new Watcher()添加回調來接收數據變化的通知
相關文章
相關標籤/搜索