JavaScript組件化開發實戰——TodoMVC

1 簡介html

TodoMVC(http://todomvc.com/)這個開源項目是幫助小夥伴們選擇合適的MV*框架。TodoMVC旨在用各類框架實現TodoList的增、刪、改、查功能,麻雀雖小,五臟俱全,是供小夥伴學習、練習、再學習的好例子。
這裏寫圖片描述
這裏寫圖片描述前端

(看看人家老外的例子,再看看我們過來的例子。。。哎)jquery

2 個人版本git

雖然官網上有各類實現版本,但彷彿缺乏那麼一個版本,就是,就是。。。我實現的版本。爲此,本猿拋磚引玉,用RequireJs+jQuery實現一個組件化的TodoMVC。github

源碼地址: https://github.com/Asrocky/iTodoMVC/tree/master瀏覽器

之因此沒有用到高級的前端MV框架,如AngularJs、ReactJs+Flux等,是爲了幫助你們學習前端組件化開發思想。同時,也但願你們將這種較爲單純的實現方法與其它前端MV框架進行對比,理解其它框架的實現初衷和原理。mvc

本猿實現的這個版本有如下兩大特色:app

1) 組件之間的關係可視化:
在頁面上右鍵「審查元素」就能經過註釋,清楚地看見組件之間的關係(以下圖)。這些註釋是經過覆寫jquery的html、append等函數實現的,並不須要程序猿本身去打印註釋。這樣一來,調試或修改代碼時就可以快速定位代碼的出處,即便不是本人寫的代碼,調試起來也很輕鬆。當須要正式發佈代碼時,能夠經過設置一個參數來關閉這個註釋功能。
圖片描述框架

2) 組件之間不直接調用對方的函數,而是經過消息來完成交互。
這裏寫圖片描述dom

如上圖所示,我設計了兩種消息,一種是請求消息(request),一種是觸發消息(trigger)。

請求消息(request):意思是當這個組件要作某個操做,好比添加Todo,它便發起「addTodo」這個消息,並附帶上newTodo這個參數。至於誰來實現這個請求,它不關心。

觸發消息(trigger):意思是當這個組件完成了某個操做,好比成功添加Todo,它便觸發「NewTodo_addTodo」這個消息,誰關心這個消息,誰就把本身的函數綁定到這個消息上。

請求消息與觸發消息的最大區別是:請求消息只會有一個實現,一對一的關係,並且每每會返回處理後的結果;而觸發消息是一對多的關係,就像廣播消息同樣,誰關心誰監聽,一旦有這個消息觸發,便執行相關操做。

具體實現代碼請查看TodoApp\utils\base.js(代碼很挫,只供學習參考)
這裏寫圖片描述

這裏寫圖片描述

3 實現

Talk is cheap, show me the code!——忍不住引用一下Linus Torvalds的名言。但在看代碼前,先看看項目完成後的代碼目錄結構,方便理解。
這裏寫圖片描述

3.1 拆分組件
這裏寫圖片描述

假設下面是設計工程師給你的靜態頁面(\TodoApp\ _static_TodoApp.html),咱們首先要作的事情是用組件化的思惟,將其分爲若干個組件來動態渲染。
這裏寫圖片描述

何爲組件?組件就是你給我一個錨點——一個section,一個div,或者一個span,我就在這個錨點指定的空間內渲染組件內容。

如何拆分?請遵照兩個原則:

一、一切皆組件:咱們將TodoApp這個應用看做一個大組件,它嵌套了三個子組件:NewTodo組件、ListTodo組件、SortTodo組件。而ListTodo組件又嵌套了子組件TodoItem。

二、單一職責原則:組件的功能儘量地單一明瞭,不要將太多的功能設計到同一個組件中。功能多了,就想辦法設計子組件,將功能分拆出去。

根據上面提到兩個設計原則,咱們將這個靜態頁面代碼分拆成5個組件,它們的關係和功能以下:
這裏寫圖片描述

3.2 構建組件

根據上述的設計,咱們將設計好的組件構建出來。從MVC的角度分析,其關係以下圖所示。
這裏寫圖片描述

但這樣的模型存在一些明顯的弊端:

1) 組件之間的交互是直接經過調用對方的函數來實現,耦合性高,不易維護與擴張。

2) 組件直接訪問與操做數據儲存(Storage),這個Storage多是服務端,也多是本地存儲,不論是什麼,直接訪問與操做會致使代碼維護與擴展的極爲不靈活。

好比說項目的先後臺並行開發。前端數據的存儲操做經過一個假服務端或瀏覽器的本地存儲來完成。若是你將這部分操做直接寫在組件的代碼中,之後改你代碼的同事必定會罵你九條街。
這裏寫圖片描述
3.3 增長Service層
爲了下降組件與Storage層的耦合性,咱們能夠增長一個Service層,專門負責模型的增刪改查等操做。你也能夠將這個Service層理解成Model層,由於它封裝了模型的全部操做。
這裏寫圖片描述

但目前組件之間的耦合性依然很高。好比如今增長了一個新模塊ProjectApp,要求當TodoApp新增Todo時,ProjectApp也要作出聯動響應。那麼你不得不找到TodoApp中新增Todo的代碼進行修改。大部分人遇到這種狀況都會來一句——找你妹的代碼!

3.4 增長消息中間件

以前已經提到過,本實例中的組件是經過消息來完成交互的。但問題就來了,消息都發到哪了?誰來處理這些消息了?若是直接在各個組件中監聽、處理消息,將會致使一個消息被髮送後,不知道誰會處理了這個消息。代碼維護起來十分困難。

爲此,咱們能夠增長了一個特殊的組件——消息中間件msgHub。

這裏寫圖片描述

請求消息的實現與觸發消息的綁定都是在msgHub中完成。如此一來,之後變動或擴展項目,只須要在msgHub中修改消息與函數之間的綁定關係便可(TodoApp\comps\ msgHub.js)。

這裏寫圖片描述

夜已深,有空再將詳細介紹代碼。歡迎交流拍磚。

相關文章
相關標籤/搜索