前端框架沉思錄(上)

這是一個前端框架滿天飛的時代,你尚未學會其中的一個,新的又出現了。更糟糕的是,你花大力氣所學習到的內容可能已通過時了。雖然說學習是一生的事,但在軟件開發領域,你不能太盲目,你必須要有是非分明的能力以及快速學習的能力。是非分明有助於淘汰那些不值得學習的目標,快速學習能夠避免學完就過期的尷尬。對於大部分人而言,這些能力是難以在短時間內習得的,這須要長期的實踐、思考與總結。本人使用過很多框架,也寫過框架,有一些這方面的心得體會,現分享出來,但願對於衆多的初學者能有些許的啓發,儘可能少走些彎路。固然,這些只是我的的一些認識,若有不當或者爭議之處,歡迎探討。css

這篇文章雖然說是講前端框架的,但其中的許多內容具備普適性,對於後端也是適用的,你能夠把其中的觀點天然地遷移到你所熟悉的後端編程語言中。爲了不陷於介紹繁瑣的基礎細節,這裏假定讀者對於面向對象程序設計已經有了必定的認識。html

兩個事實

在繼續進行下面的內容以前,須要先給出兩個事實。後面對於一些問題的處理均可以在這兩個事實中找到根據或者動機。前端

  1. 咱們難以認知或者構建無序的複雜的軟件系統vue

  2. 咱們有辦法認知或者構建有序的複雜的軟件系統編程

這裏有必要對 無序有序 做一些說明。無序的軟件系統是指無章法的,沒有依賴成熟的理論方法構建的軟件系統。而有序的軟件系統則相反,它相身是有明顯的結構而且是易於理解的。另外,這裏的 複雜 主要指的軟件系統規模達到必定的水平。後端

從這兩個事實出發,如今咱們能夠給出一個理想的框架所能實現的目標:能夠經過該框架構建有序的複雜的軟件系統,或者說經過該框架構建的複雜的軟件系統是易於認知的。sass

傳統網頁的構建的問題所在

既然講的是與前端框架相關的內容,那麼咱們有必要從新審視下,在無框架使用的條件下,對於傳統網站頁面,咱們是如何構建的。咱們通常會這麼作,在 html 文件中寫上衆多的標籤和內容。而後,通常狀況下還會有一些相關 js 文件與 css 文件。js 文件與 css 文件用於操做或者描述 html 文件中的內容。前端框架

上面一段講述的頁面構建方案,如今還有許多人在用,對於簡單的頁面尚可,但若是所要構建的頁面足夠的複雜,對於頁面的維護會是一個不小的負擔。這主要體如今下面兩個方面:首先,大量存在的 id 屬性值或者類屬性值容易致使命名衝突;其次,在添加新功能或者擴展新功能時,將難如下手。架構

從上面的分析,咱們能夠看出經過傳統方式來構建複雜的頁面是行不通的,那麼問題出在哪裏?若是你將上述頁面的總體結構與面向對象程序設計中類的結構作個對比,你會發現,該結構有數據對象(html 標籤與內容)、有操做(js 代碼與 css 描述)。這顯然就是一個 嘛!因此問題的關鍵在於它把全部的邏輯都寫在一個 裏了。因此,解決這個問題的思路是分解並重組該 ,下降構建的複雜度。這樣咱們就獲得理想框架應該有的第一個功能:提供面向對象編程語言裏面類的結構來分解複雜的目標系統。在前端,這種結構通常被叫作組件。框架

組件化

目前,已經有很多框架就上述問題作了嘗試,React 是其中的一個表明,它經過 React.createClass 來建立組件。以下面的示例所示:

var Hello = React.createClass({
  render: function() {
    return <h1 className='hello'>Hello World!</h1>;
  }
});

React 的組件化方案並不完美,這主要體如今對樣式的處理上,它並沒解決全局樣式的衝突問題。大部分的人仍然經過命名約定或者使用 less/sass 來實現曲線救國。雖然有一些 CSS in JS 的第三方方案,但解決起來總以爲很是彆扭。不過 CSS in JS 的方案卻爲咱們對問題的解決打開了一道窗。下面是 xmlplus 的解決方案,堪稱完美。

Hello: {
    css: `#hello { color: blue; }`,
    xml: `<h1 id='hello'>Hello World</h1>`,
    fun: function(sys, items, opts) {
        sys.hello.css("font-size", "28px");
    }
}

理解該示例的關鍵在於視圖項中 id 標識符。它是局部的,僅在組件內部可訪問,在函數項中對其操做與在樣式項中對其描述,本質上沒什麼差異,最終都是對目標對象施加影響。這種處理方式是優勢遠不止對上述問題的解決,更多內容能夠訪問文檔的相關章節。這一節請注意 局部化 思想的應用,後面內容將反覆使用它來解決相關的問題。

組件之間的通訊

回到頁面的設計,當咱們對一個頁面進行組件化分割後,原來頁面內能夠直接通訊的對象有可能被割裂開來。一個理想的前端框架應該可以提供修復這種通訊關係的能力,這就是組件之間的通訊。

按不一樣組件的關係劃分,組件之間的通訊能夠分爲父子組件和任意組件之間的通訊。其中父子組件之間主要經過事件的傳遞和直接可見的接口來通訊,這一方面不少主流框架都會提供,因此這裏將集中注意力討論的任意組件之間的通訊機制。相對於任意組件之間的通訊,比較遺憾的是目前主流的框架都在努力實現數據的綁定來避免操做 DOM 就能更新視圖之類非必要的功能。

一個示例

首先,明確一點,一個應用就是一棵組件樹。爲方便起見,下面以 xmlplus 中的例子來講明,固然,你也能夠聯繫到 React 或者 vue 中的組件樹。

Example: {
    xml: `<div id='index'>
             <Hello id='foo'/>
             <World id='bar'/>
          </div>`,
    fun: function(sys, items, opts) {
        console.log("communication test");
    }
}

此示例經過兩個組件節點 Hello 與 World 之間的通訊來演示任意組件之間的通訊。上述 Hello 組件與 World 組件的內容以下:

Hello: {
    xml: `<button id='hello'>Hello</button>`,
    fun: function(sys, items, opts) {
        this.on("click", e => this.notify("hello", "msg"));
    }
},
World: {
    xml: `<h1 id='world'>World</h1>`,
    fun: function(sys, items, opts) {
        this.watch("hello", (e, msg) => console.log(msg));
    }
}

觀察此組件 Index,咱們能夠分解出以下的組件樹:

Example/
└── div[index]
    ├── Hello[foo]
    │   └── button[hello]
    └── World[bar]
        └── h1[world]

通訊的局部化

若是隻實例化一個 Example 組件上述示例能很好的工做,但若是實例化多個 Example 組件就會出問題了。咱們來看看具體的示例:

Index: {
    xml: `<div id='index'>
              <Example id='foo'/>
              <Example id='bar'/>
          </div>`,
    fun: function(sys, items, opts) {
        console.log("two Examples");
    }
}

該示例中,點擊其中一個 Hello 按鈕,將致使全部消息偵聽器接收到消息,這顯然不是咱們想要的。因此咱們須要對消息進行局部化。請看下面改進後的 Example 示例,改示例在映射項中配置了一個值爲 truemsgscope 選項,這將致使當前組件及其子組件消息通訊的局部化。局部化的區域能夠參考上面給出的組件樹視圖。

Example: {
    xml: `<div id='index'>
             <Hello id='foo'/>
             <World id='bar'/>
          </div>`,
    map: { msgscope: true },
    fun: function(sys, items, opts) {
        console.log("communication test");
    }
}

總結

通訊的局部化帶來兩個好處,一個是避免消息污染,另外一個是當一個應用足夠複雜時,全局的通訊將不可避免地陷入混亂。通訊的局部化的想法與組件思想一模一樣,都是爲了應對構建複雜系統服務的。

目前主流的框架並不提供組件之間的通訊功能,同時第三方的通訊軟件包通常也不會提供通訊的局部化功能。爲了應對構建複雜的系統,你能夠在消息的命名上做文章,儘管麻煩一點。

本文講了一個理想框架應該包含兩個最基本的功能,一個是優秀的組件化能力,另外一個局部化的通訊功能。前者在不少面向對象編程語言中都會包含,後者通常只能實現全局的通訊功能,但讀者應該有局部化的通訊意識。

下一章咱們將討論命名空間、組件對象共享以及延遲實例化等錦上添花的框架應該提供的功能,敬請期待。

相關文章
相關標籤/搜索