BiuJS[v1.0]說明文檔(1):整體結構

biu

BiuJS

BiuJS是一個輕巧的mvvm框架
它實現了數據的雙向綁定
並提供一些基本的指令幫助你提高效率,好比 $for$model$if$click$style
是的,如你所見,以 $開頭的指令是它的獨特標識
1000行左右的代碼量,讓應用的開發和加載biu的一瞬完成
BiuJS倉庫: https://github.com/veedrin/biu

啓動

首先咱們來看一下BiuJS是如何啓動的javascript

let app = new Biu({
    mount: '#app',
    data: {
        me: 'BiuJS'
    },
    action: {
        change: function() {
            console.log('changed');
        }
    }
});

mount是BiuJS的掛載點,它決定BiuJS在多大範圍的DOM樹內起做用,而且它只能識別id選擇器html

data是BiuJS的數據模型,頁面就是經過綁定這裏的數據實現自動更新的java

action是BiuJS的方法集合,藉此實現行爲邏輯node

劫持

JavaScript提供了一個強大的接口Object.defineProperty,經過它咱們能夠劫持對象的gettersettergit

也就是說,被劫持過的數據,若是值發生了變化,就會觸發settergithub

Object.defineProperty(data, key, {
    enumerable: true,
    configurable: true,
    get: function() {
        return value;
    },
    set: function(newValue) {
        console.log('changed');
    }
});

假如咱們在setter里加個回調函數,在回調函數中把新值寫進DOM裏,數據變化與頁面變化同步不就實現自動化了麼?數組

Object.defineProperty(data, key, {
    enumerable: true,
    configurable: true,
    get: function() {
        return value;
    },
    set: function(newValue) {
        callback(newValue);
    }
});

function callback(newValue) {
    node.innerHTML = newValue;
}

對,這就是BiuJS的命脈所在,很簡單吧!app

不過,爲了進一步提高效率,咱們還有大量工做要作。接着往下看框架

訂閱

若是數據變化要與多處頁面的變化同步,這時候就須要一個工具來統一接收更新了mvvm

咱們把DOM元素與回調函數打包在一塊兒,依次扔進一個數組裏,當數據觸發setter的時候,再用一個函數遍歷這個數組,依次調用回調函數,一對多的同步自動化也被咱們實現了

Object.defineProperty(data, key, {
    enumerable: true,
    configurable: true,
    get: function() {
        return value;
    },
    set: function(newValue) {
        notify(newValue);
    }
});

function notify(newValue) {
    for (let i = 0; i < array.length; i++) {
        array.update(newValue);
    }
}

這個行爲有點像送報紙,因此咱們稱之爲訂閱,訂閱的人再多,都不會手忙腳亂

訂閱器

看起來頗有道理,但是訂閱這個行爲究竟是怎麼實現的呢?

首先要明確一點,那個數組(訂閱清單)在數據那裏,不然setter怎麼觸發數組呢!

因此咱們要遠程訂閱

還記得咱們有一個getter嗎?它可不是吃乾飯的。只要咱們訪問數據的值,就會觸發getter

那咱們是否是能夠給getter打個電話,讓它幫咱們訂閱呢?

getter是個寂寞的老人,時不時的看望它一下,它什麼都會答應你

因此咱們只要訪問一下數據的值,而後在getter裏把訂閱者push進數組裏,遠程訂閱就作到了

Object.defineProperty(data, key, {
    enumerable: true,
    configurable: true,
    get: function() {
        array.push(subscriber);
        return value;
    },
    set: function(newValue) {
        console.log('changed');
    }
});

編譯

最後一個問題,DOM元素是如何與數據對應起來的?

它們倆是沒法溝通的,須要找個翻譯

把DOM元素裏的模板分析一下,找出裏面的變量和特定語法,這個過程叫模板編譯

舉個簡單的例子

<div>{{name}}</div>

咱們一眼就看出來,鬍子模板裏的name是一個變量,程序可看不出來,除非你給它一套邏輯,這套邏輯就是編譯器

認出了name,咱們才能夠到對應數據的數組裏添加訂閱

不然,上錯花轎可保不許嫁對郎哦

流程

到這裏,整個流程纔算跑起來了

  1. 首先,劫持全部的數據
  2. 而後,編譯模板,找到對應的數據
  3. 經過訪問這個數據,觸發getter,在對方的數組裏添加一個訂閱位
  4. 坐等數據更新,觸發setter,遍歷數組,調用數組裏的全部回調
  5. 回調裏愛幹嗎幹嗎,不過別忘了咱們的初衷:頁面同步更新

有了這一套自動化系統,你只要把數據綁在模板裏,接下來頁面就活了

雙向綁定

誒,不是說好了雙向綁定嗎?怎麼,是個瘸子呀?

你仔細想想,把數據與頁面綁定在一塊兒,這是毫無疑問可以實現的

可是把頁面與數據綁定在一塊兒,這是啥意思呢?

還真有辦法,就是輸入框。頁面能產生數據的地方也只有輸入框了

並且這個綁定也不稀奇,輸入框都有輸入事件,把獲取到的新值賦給數據就行了

<input class="input" type="text">
<div class="div"></div>

<script type="text/javascript">
    let input = document.querySelector('.input');
    let div = document.querySelector('.div');
    input.addEventListener('input', function(event) {
        div.innerHTML = event.target.value;
    });
</script>

這裏沒有數據的參與,但也能產生一個反向綁定的假象

雙向綁定就好像說,你看你美國挺強大,但我阿根廷足球也不賴呀,咱們結成對等的戰略合做夥伴吧!

因此恕我直言,雙向綁定實際上是個噱頭,重要的是訂閱

接口

對了,咱們還須要提供一個統一的對外接口

當仁不讓,就叫Biu吧

用一個當即執行函數包裹,再把統一接口掛載到window上,就能夠在外部使用了

(function(root) {
    function Biu(options) {
        this.mount = options.mount;
        this.data = options.data;
        this.action = options.action;
    }
    root.Biu = Biu;
})(window);

寫在後面

以上就是BiuJS大致的結構

歡迎到BiuJS倉庫: https://github.com/veedrin/biu瞭解詳情

更歡迎StarFork

相關文章
相關標籤/搜索