組件化的前世今生

很多年以前,我們寫(xiě)網(wǎng)頁(yè)的時(shí)候都是這樣的:根據(jù)設(shè)計(jì)稿寫(xiě)好一個(gè)頁(yè)面的html和css,然后再去寫(xiě)js來(lái)做一些交互纱控。如果遇到同樣功能的代碼牙言,最簡(jiǎn)單粗暴的方式是復(fù)制粘貼酸钦,如果為了更好的復(fù)用性,就封裝個(gè)jquery的插件咱枉,需要用的時(shí)候就引入插件卑硫,調(diào)用初始化的方法,傳入?yún)?shù)蚕断,比如一個(gè)日歷欢伏、一個(gè)輪播圖。在那個(gè)web野蠻生長(zhǎng)的年代亿乳,這樣的插件產(chǎn)生了很多颜懊,那個(gè)時(shí)代的前端工程師必須會(huì)自定義jquery的插件。那時(shí)候也有一些組件庫(kù),比如extjs河爹、bootstrap匠璧、jquery ui等。

但是這種組件的方案或者說(shuō)jquery本身就有很多問(wèn)題:

  • 瀏覽器端效率最低的就是dom操作咸这,因?yàn)闀?huì)觸發(fā)reflow夷恍,repaint,jquery是操作dom的一個(gè)庫(kù)媳维,基于jquery封裝的插件當(dāng)然也避免不了頻繁的操作dom酿雪,所以這樣的的插件如果代碼寫(xiě)的時(shí)候不注意,效率很可能會(huì)比較低侄刽。
  • jquery只是一個(gè)庫(kù)指黎,而不是決定代碼組織方式的框架,沒(méi)有固定的代碼規(guī)范州丹,每個(gè)人都會(huì)有自己的編碼風(fēng)格醋安,雖然可以規(guī)定一些規(guī)范,但畢竟不是強(qiáng)制的墓毒。如果團(tuán)隊(duì)成員吓揪,項(xiàng)目規(guī)模比較小的時(shí)候還好,隨著項(xiàng)目所计、團(tuán)隊(duì)規(guī)模的擴(kuò)大柠辞,這樣的代碼會(huì)越來(lái)越難以維護(hù)和復(fù)用。

現(xiàn)在的組件化的方案已經(jīng)在那個(gè)時(shí)代的基礎(chǔ)上前進(jìn)了很大一步主胧。

一些常見(jiàn)的邏輯叭首,我們會(huì)把他們封裝成函數(shù)或者類(lèi),比如BaseXxx踪栋、XxxUtils焙格,牽扯到ui的組件復(fù)用的不只是邏輯,還有模板和樣式己英。也就是說(shuō)一個(gè)組件需要封裝的就是關(guān)聯(lián)的html间螟、css吴旋、js损肛。

我們可以先想想如果我們自己去做一個(gè)組件化的框架,我們會(huì)怎么做(主要考慮如何設(shè)計(jì))荣瑟。

如何去設(shè)計(jì)一個(gè)組件化的框架

模板治拿,樣式,交互邏輯

組件最基礎(chǔ)的就是這三部分笆焰。樣式我們可以不做封裝劫谅,通過(guò)全局引入然后加個(gè)命名空間的方式來(lái)區(qū)分組件。模板可以?huà)燧d到dom樹(shù)上通過(guò)選擇器來(lái)取,或者直接傳入一段模板字符串捏检。交互邏輯的部分荞驴,我們會(huì)通過(guò)事件綁定調(diào)用組件上的一些方法。

 class Component{
    constructor({el,template,onXxx}){
      this.el  = el;
      this.template = template;
      this.onXxx = onXxx;

      this.render();
      this.bindEvents();
    }
    render(){
         var ele = document.querySelector(this.el);
         ele.innerHTML = this.template;
   }
    bindEvents(){
        this.el.querySelector('xx').addEventListener('click', this.onXxx)
    }
 }

現(xiàn)在我們的組件有了最初的模型贯城,模板熊楼,邏輯,事件綁定能犯,可以傳參數(shù)來(lái)進(jìn)行一些定制鲫骗。

模板引擎

現(xiàn)在我們把需要把數(shù)據(jù)填充到模板需要用拼接字符串的方式,這樣的代碼寫(xiě)起來(lái)很是繁瑣踩晶,針對(duì)這個(gè)問(wèn)題执泰,已經(jīng)有了成熟的解決方案,我們可以選用某一個(gè)模板引擎渡蜻,像ejs术吝,jsmart,jade之類(lèi)的晴楔。但是我們需要的是一個(gè)能和我們的組件結(jié)合緊密的一個(gè)模板引擎顿苇,我們需要自己實(shí)現(xiàn)一個(gè),這樣税弃,我們可以直接直接取組件中的數(shù)據(jù)纪岁,調(diào)用組件的某個(gè)方法,甚至自己擴(kuò)展一些模板的功能则果。
比如幔翰,我們?nèi)绻雽?shí)現(xiàn)這樣一個(gè)模板引擎,

  <table>
        <my:forEach  items="goodsList"  var="goods">
            <td>${goods.name}</td>
            <td>${goods.price}</td>
            <td>${goods.amount}</td>
        </my:forEach>
  </table>

看上去是不是比較像jsp的語(yǔ)法西壮,其實(shí)jsp就是一個(gè)專(zhuān)用的模板引擎遗增,他有page,session,application,request,response等隱式對(duì)象,可以直接取幾個(gè)域中的數(shù)據(jù)款青,而且也可以支持自定義標(biāo)簽和自定義el函數(shù)做修。
想想該怎么實(shí)現(xiàn)。一種思路是通過(guò)xml的解析抡草,xml解析方式有dom和sax兩種饰及,就是分析出有什么標(biāo)簽有什么屬性。然后對(duì)應(yīng)的屬性做什么操作康震。屬性和對(duì)應(yīng)操作我們給封裝起來(lái)燎含,叫做指令。開(kāi)發(fā)者可以自己去注冊(cè)一些自定義的指令腿短。模板在解析的時(shí)候解析出對(duì)應(yīng)的屬性就會(huì)執(zhí)行對(duì)應(yīng)的操作屏箍。

通過(guò)模板解析的方式來(lái)初始化

我們組件用的時(shí)候绘梦,需要new一個(gè)組件的對(duì)象,傳入需要的參數(shù)赴魁。比如:

  new Component({
     template:"<div><h1>title</h1><p>content</p></div>",
     onXxx: function(){}
 });

想一下卸奉,我們?nèi)绻氩煌ㄟ^(guò)js來(lái)初始化,想通過(guò)下面這種方式來(lái)初始化該怎么做颖御,

<Component  template="xxxx"   onXxx=""></Component>

我們之前自己實(shí)現(xiàn)了一個(gè)模板引擎择卦,除了自定義指令的解析,當(dāng)然也會(huì)把自定義組件的解析加進(jìn)去郎嫁。這樣一棵組件樹(shù)秉继,我們只需要調(diào)用一次初始化方法,然后在解析組件樹(shù)模板的過(guò)程中泽铛,把一個(gè)個(gè)組件初始化尚辑,組裝好。這一些都是用戶(hù)感知不到的盔腔,用戶(hù)只需要寫(xiě)模板杠茬。

雙向綁定MVVM

現(xiàn)在我們的組件還是避免不了要大量的操作dom,這必定會(huì)有很多的性能問(wèn)題弛随。能不能把dom操作也給封裝起來(lái)瓢喉,開(kāi)發(fā)者不需要再去操作dom,只需要管理好數(shù)據(jù)就可以了呢舀透。
想一下后端開(kāi)發(fā)栓票,最頻繁的就是增刪改查,這樣的sql語(yǔ)句是經(jīng)常要寫(xiě)的愕够,于是后端有了orm框架走贪,比如hibernate,映射好實(shí)體類(lèi)和數(shù)據(jù)表惑芭,類(lèi)的屬性和字段的關(guān)系之后坠狡,只需要調(diào)用hibernate提供的Session類(lèi)的增刪改查的方法就好了,sql語(yǔ)句會(huì)自動(dòng)生成遂跟,比如mybatis逃沿,映射好方法和寫(xiě)在xml中的sql語(yǔ)句的關(guān)系,之后只要調(diào)用對(duì)應(yīng)的方法就可以了幻锁,不需要自己去寫(xiě)sql語(yǔ)句凯亮。
數(shù)據(jù)庫(kù)中的表和java的實(shí)體類(lèi)建立了映射關(guān)系就能夠做到開(kāi)發(fā)時(shí)不需要寫(xiě)sql語(yǔ)句,那么我們建立好數(shù)據(jù)和dom越败,也就是model和view之間的關(guān)系是不是也就可以不寫(xiě)任何一句dom操作的代碼触幼,只去管理數(shù)據(jù)呢硼瓣,然后view會(huì)自動(dòng)同步呢究飞。
當(dāng)然是可以的置谦,從model到view的綁定,我們可以監(jiān)聽(tīng)model的變化亿傅,變化的時(shí)候就去通知view中的Observer媒峡,然后那個(gè)Observer去操作dom,去更新視圖葵擎。
監(jiān)聽(tīng)model的變化谅阿,很容易想到的是es5中的Object.defineProperty這個(gè)api,他可以定義set方法酬滤,攔截對(duì)對(duì)象屬性的賦值操作签餐。

 //觀察者的隊(duì)列
  var observers = [];
  observers.push(new Observer({...}));

  var obj = {};
  var value = "";
  Object.defineProperty(obj, 'name', {
    get: function() {
      return value;
    },
    set: function(val) {
       value = val;
      //數(shù)據(jù)改變,通知觀察者盯串,去更新view
      var target = this;
       observers.forEach(function(observer,index){
              observer.notify(target);
       });
    }
  });

當(dāng)然es6提供的Proxy這個(gè)更高層次的封裝類(lèi)也可以氯檐。

  // 觀察者的隊(duì)列
  var observers = [];
  observers.push(new Observer({...}));

 let obj = {};
 let proxy = new Proxy(obj, {
  get: function (target, key, receiver) {
    return Reflect.get(target, key, receiver);
  },
  set: function (target, key, value, receiver) {
     Reflect.set(target, key, value, receiver);    
     for(let observer in observers){
         observer.notify(this);
     }
 }
})

至于從view到model的綁定,其實(shí)就是監(jiān)聽(tīng)用戶(hù)輸入的一些操作体捏,監(jiān)聽(tīng)表單的事件冠摄,然后去根據(jù)用戶(hù)輸入的數(shù)據(jù)和映射關(guān)系,去同步model几缭。

生命周期函數(shù)

我們把dom操作給封裝了河泳,也就是把dom元素的增刪改給自動(dòng)化了,組件對(duì)應(yīng)的dom元素的創(chuàng)建和銷(xiāo)毀或者是重新繪制更新dom的時(shí)候年栓,想做一些操作拆挥,就不能做了,所以我們要在這些時(shí)刻暴露一些鉤子某抓,讓開(kāi)發(fā)者可以在這些時(shí)候去做一些操作竿刁。比如組件的dom初次渲染完的時(shí)候要去請(qǐng)求數(shù)據(jù),比如組件銷(xiāo)毀的時(shí)候要做一些資源釋放的工作避免內(nèi)存泄漏等搪缨。主要的生命周期鉤子函數(shù)就這么四類(lèi)食拜,創(chuàng)建前后,掛載到dom前后副编,更新前后,從dom中移除(銷(xiāo)毀)前后负甸。
生命周期的名字可以叫beforeCreatecreated痹届,beforeMount呻待,mountedbeforeUpdate队腐,updated蚕捉,beforeDestroydestroyed柴淘,
也可以叫componentWillMount迫淹,componentDidMount秘通,componentWillUpdatecomponentDidUpdate敛熬,componentWillUnmount肺稀,componentDidUnmount等。

虛擬dom和diff算法

現(xiàn)在我們的組件渲染是直接渲染到dom元素应民,并且是全局的渲染话原。model改變不大的時(shí)候,也會(huì)全局重新渲染一次诲锹,會(huì)有很多不必要的dom操作繁仁,性能損耗。我們知道归园,計(jì)算機(jī)領(lǐng)域很多問(wèn)題都可以加一個(gè)中間層來(lái)解決改备,這里也一樣,我們可以不直接渲染到真實(shí)dom元素蔓倍,用js對(duì)象來(lái)模擬真實(shí)dom元素悬钳,每次渲染渲染成這樣的一顆虛擬dom元素組成的樹(shù)。

  {
      name: 'a',
      props: {
        
      },
      children: [
          {
              name: 'a-1',
              props:{},
              children:[]
          },
          {
              name: 'a-2',
              props:{},
              children:[]
          },
          {
              name: 'a-3',
              props:{},
              children:[]
          }
      ]
  }

這樣可以把上一次的渲染結(jié)果保留偶翅,下次渲染的時(shí)候和上一次的渲染結(jié)果做對(duì)比默勾,比較有沒(méi)有變化,有變化的話(huà)找出變化的部分聚谁,局部增量的渲染改變的部分母剥。這樣能避免不必要的dom操作帶來(lái)的性能開(kāi)銷(xiāo)。比較的過(guò)程我們可以叫他diff算法形导。
引入了虛擬dom這一層环疼,雖然會(huì)增大計(jì)算量和內(nèi)存消耗,但是卻減少了大量的dom操作朵耕。性能會(huì)有明顯的提升炫隶。

Immutable

我們會(huì)在model變化以后去更新view,但是model有沒(méi)有變化需要和之前的model做對(duì)比阎曹,model是一個(gè)對(duì)象伪阶,可能層次比較深,深層的比較是比較慢的处嫌,這里又會(huì)有性能的問(wèn)題栅贴。針對(duì)這一問(wèn)題,我們應(yīng)該怎么去優(yōu)化呢熏迹?
我們都知道字符串是常量檐薯。jvm的內(nèi)存空間分為堆、棧注暗、方法區(qū)坛缕、靜態(tài)域4個(gè)部分墓猎,方法區(qū)中有個(gè)字符串常量池,來(lái)存放字符串祷膳。也就是我們創(chuàng)建一個(gè)字符串,如果常量池中有的話(huà)屡立,他會(huì)直接把引用返回給你直晨,如果沒(méi)有的話(huà)會(huì)創(chuàng)建一個(gè)字符串然后放入常量池中。對(duì)字符串的修改會(huì)創(chuàng)建一個(gè)新的字符串膨俐,而不是直接修改原字符串勇皇。編程語(yǔ)言基本都是這樣處理字符串的,好處也是很明顯的焚刺,設(shè)想一下敛摘,如果有一個(gè)長(zhǎng)度為1000的字符串,要和另一個(gè)字符串做比較乳愉,那么如果字符串不是常量兄淫,那么完成比較就要要遍歷字符串的每一個(gè)字符,復(fù)雜度為o(n)蔓姚。但如果我們把字符串設(shè)計(jì)為常量捕虽,比較時(shí)只需要比較兩個(gè)字符串的內(nèi)存地址,那么復(fù)雜度就降到了o(1)坡脐。這種優(yōu)化的思路是典型的空間換時(shí)間泄私。

組件的model我們也可以實(shí)現(xiàn)為不可變(immutable)的,這樣比較的時(shí)候只需要比較兩個(gè)model的引用就可以了备闲,會(huì)使性能又有一個(gè)大的提高晌端。

fiber

想一想我們的組件化框架還有哪里有問(wèn)題。
我們知道瀏覽器中每個(gè)頁(yè)面是單線(xiàn)程的恬砂,渲染和js計(jì)算共用一個(gè)線(xiàn)程咧纠,會(huì)相互阻塞。
model改變后要生成虛擬dom泻骤,生成虛擬dom惧盹、虛擬dom之間的diff可能會(huì)計(jì)算比較長(zhǎng)的時(shí)間,如果這時(shí)候頁(yè)面上有個(gè)動(dòng)畫(huà)在同時(shí)搶占著主線(xiàn)程瞪讼,那么勢(shì)必會(huì)導(dǎo)致動(dòng)畫(huà)的卡頓钧椰。每個(gè)痛點(diǎn)的解決,都能會(huì)帶來(lái)性能的提升符欠,為了追求極致的性能嫡霞,這個(gè)問(wèn)題我們也要想辦法解決。

虛擬dom是一顆樹(shù)形的結(jié)構(gòu)希柿,生成或比較一般都是遞歸的過(guò)程诊沪。我們知道所有的遞歸都可以改成循環(huán)的方式养筒,只要我們可以一個(gè)隊(duì)列來(lái)保存中間狀態(tài)。把遞歸改成循環(huán)后端姚,就可以異步化分段執(zhí)行了晕粪。先執(zhí)行一段計(jì)算,然后把執(zhí)行狀態(tài)保存渐裸,釋放主線(xiàn)程去做渲染巫湘,渲染完之后再去做之后的計(jì)算。這樣就完美的解決了瀏覽器環(huán)境下計(jì)算和渲染之間相互阻塞的問(wèn)題了昏鹃,性能有了進(jìn)一步的提升尚氛。
這種資源的競(jìng)爭(zhēng)在計(jì)算機(jī)中隨處可見(jiàn),就像cpu的進(jìn)程調(diào)度洞渤,每個(gè)進(jìn)程的計(jì)算都要用到cpu阅嘶,操作系統(tǒng)就需要用一種合理的方式來(lái)分配cpu資源。cpu調(diào)度策略有很多幾種载迄,比如分時(shí)讯柔,按照優(yōu)先級(jí)等等,都是把一個(gè)大的計(jì)算量給分成多次來(lái)執(zhí)行护昧,暫停執(zhí)行的時(shí)候把上下文信息保存下來(lái)磷杏,得到cpu的時(shí)候再恢復(fù)上下文繼續(xù)執(zhí)行。
計(jì)算量分段捏卓,類(lèi)似切菜极祸,我們把這種調(diào)度策略叫fiber,即纖維化怠晴。
沒(méi)有fiber之前的虛擬dom計(jì)算是這樣的


fiber之后是這樣的


完美解決了瀏覽器的單線(xiàn)程下單次計(jì)算量過(guò)大會(huì)阻塞渲染的問(wèn)題遥金。

Component-Native

之前為了減少不必要的渲染,我們加了個(gè)中間層-虛擬dom蒜田,除了可以帶來(lái)性能的提示之外稿械,我們可以有一些別的思考,比如我可不可以不只渲染成dom元素冲粤,渲染成安卓美莫、ios原生的組件?
經(jīng)過(guò)思考梯捕,我們覺(jué)得這是可行的厢呵,邏輯依然用js來(lái)寫(xiě),通過(guò)jscore來(lái)執(zhí)行js傀顾,js需要調(diào)用的原生api由框架封裝襟铭,提供給js。渲染部分,建立原生組件和和模板中組件的映射關(guān)系寒砖,渲染的時(shí)候生成對(duì)應(yīng)的原生組件赐劣。邏輯的部分可以復(fù)用,除了渲染的是原生的組件哩都,別的功能依然都有魁兼。



思路是可行的,但是實(shí)現(xiàn)這些組件漠嵌、提供供js調(diào)用的原生api咐汞,工作量肯定比較大,而且會(huì)有很多坑献雅。

全局狀態(tài)管理

組件之間可以通過(guò)傳遞參數(shù)來(lái)通信碉考。如果只是父子組件通信比較簡(jiǎn)單塌计,但是如果需要通信的兩個(gè)組件之間間隔的層次比較多挺身,或者是兄弟組件,那么之間互相通信就很麻煩了锌仅,需要多層的傳遞或者是通過(guò)父組件做中轉(zhuǎn)章钾。針對(duì)這個(gè)問(wèn)題,有沒(méi)有什么別的思路呢热芹?
其實(shí)可以引入一個(gè)中介者來(lái)解決贱傀,就像婚姻中介,如果男方自己去找女方伊脓,或者女方自己去找男方都不太方便府寒,這時(shí)候可以找一個(gè)中介,男方和女方分別在那里注冊(cè)自己的信息报腔,然后等中介有消息的時(shí)候通知自己株搔。這樣男方和女方就不需要相互聯(lián)系,只要和婚姻中介聯(lián)系就可以了纯蛾。



類(lèi)似的纤房,我們可以創(chuàng)建一個(gè)store來(lái)存儲(chǔ)全局的信息,組件在store那里注冊(cè)翻诉,當(dāng)一個(gè)組件向store發(fā)送消息的時(shí)候炮姨,監(jiān)聽(tīng)store的組件就能收到消息,從store中取出變化后的數(shù)據(jù)碰煌。


其他

關(guān)于組件的想象空間還有很大舒岸。未來(lái)可能會(huì)能夠渲染到所有的端,渲染過(guò)程中的每一個(gè)環(huán)節(jié)芦圾,每一個(gè)痛點(diǎn)都有相應(yīng)的優(yōu)化方案吁津。性能、功能都可以不斷地提升。只要我們不要停止思考碍脏、停止敲代碼的雙手梭依。

現(xiàn)在主流的組件化的框架

我們從jquery插件出發(fā),思考了很多我們想要的組件化框架的樣子典尾,回到現(xiàn)實(shí)役拴,我們看一下現(xiàn)在主流的組件化的框架有哪些,他們各自都有哪些特性钾埂。

react

  • react支持jsx的語(yǔ)法河闰,可以html和js混著寫(xiě),而不像模板引擎褥紫,需要去另外學(xué)習(xí)一套模板的語(yǔ)法姜性。
  • 有了jsx,可以直接用
      ReactDOM.render(
        <MyComponent  values="xxx"></MyComponent>,
       document.getElementById("container")
      )

通過(guò)解析jsx來(lái)初始化髓考,而不需要手動(dòng)去new一個(gè)組件對(duì)象部念。

  • react提供了從model到view的單向的綁定,state發(fā)生了變化氨菇,就會(huì)去render
  • react也提供了完善的生命周期函數(shù)供開(kāi)發(fā)者在組件創(chuàng)建儡炼、更新、銷(xiāo)毀前后進(jìn)擴(kuò)展一些功能查蓉。而且提供了componentWillReceiveProps和shouldComponentUpdate兩個(gè)用于優(yōu)化性能的生命周期函數(shù)乌询。

componentWillReceiveProps是在組件接收到新的props,還沒(méi)有render之前調(diào)用豌研,在這里去調(diào)用setState更新?tīng)顟B(tài)妹田,不會(huì)觸發(fā)額外的render。shouldComponentUpdate是在state或props變化之后調(diào)用的鹃共,根據(jù)返回的結(jié)果決定是不是調(diào)用render鬼佣, 可以和Immutable.js結(jié)合,來(lái)避免state的深層比較帶來(lái)的性能損耗及汉。沮趣。

  • react 有虛擬dom這一層,并且會(huì)通過(guò)優(yōu)化到的o(n)的diff算法來(lái)進(jìn)行虛擬dom的對(duì)比坷随。
  • react是reconsiler(調(diào)度者)房铭,react-dom是renderer。react 16使用了fiber這個(gè)新的調(diào)度算法温眉。使得大計(jì)算量被拆解缸匪,提高了應(yīng)用的可訪問(wèn)性和性能。
  • react-native提供了可以渲染成安卓类溢、ios組件的renderer凌蔬,同時(shí)提供了原生的api供js調(diào)用露懒。
  • 可以結(jié)合redux來(lái)做狀態(tài)管理

vue

  • vue提供了內(nèi)置的專(zhuān)用的模板引擎,有指令砂心、過(guò)濾器懈词、插值表達(dá)式等功能,有內(nèi)置的指令過(guò)濾器辩诞,也可以注冊(cè)自己擴(kuò)展的指令過(guò)濾器坎弯。而且提供了render函數(shù),可以結(jié)合babel來(lái)實(shí)現(xiàn)jsx的編譯译暂。
  • vue提供了雙向綁定MVVM
  • vue有完善的生命周期函數(shù)抠忘,包括create前后,mount前后外永,update前后和destory前后
  • vue2.x加入了虛擬dom崎脉,可以減少不必要的渲染
  • vue社區(qū)有weex這個(gè)做原生渲染的框架
  • vue可以結(jié)合vuex來(lái)做全局狀態(tài)管理

angular2

  • 支持模板的語(yǔ)法,指令伯顶、過(guò)濾器囚灼、插值表達(dá)式
  • decorator的方式來(lái)聲明組件
  • 支持IOC
  • 支持組件化
  • 支持雙向綁定MVVM
  • 創(chuàng)建、更新砾淌、銷(xiāo)毀前后的生命周期函數(shù)
  • 和typescript結(jié)合緊密

其他組件化的框架

實(shí)現(xiàn)組件化的框架很多啦撮,比如Avalon谭网、Ember汪厨、Konckout等等,都有各自的特點(diǎn)

WebComponents

組件化是一個(gè)趨勢(shì)愉择,現(xiàn)在有很多實(shí)現(xiàn)組件化的框架劫乱,W3C提出了web compoenents的標(biāo)準(zhǔn):。這個(gè)標(biāo)準(zhǔn)主要由4種技術(shù)組成锥涕,html import衷戈、shadow dom、custom elment和html template层坠。新的標(biāo)準(zhǔn)肯定會(huì)有兼容性的問(wèn)題殖妇,goole推出了Polymer這個(gè)基于web components規(guī)范的組件化框架。

總結(jié)

從最開(kāi)始的jquery插件破花,到現(xiàn)在的各種組件化的框架谦趣、web components標(biāo)準(zhǔn),組件化已經(jīng)是一種必然的趨勢(shì)座每,我們不僅要會(huì)去設(shè)計(jì)前鹅、封裝組件,更要去了解組件的發(fā)展的前世今生峭梳,這樣才不會(huì)在框架的海洋中迷失舰绘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子捂寿,更是在濱河造成了極大的恐慌口四,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秦陋,死亡現(xiàn)場(chǎng)離奇詭異窃祝,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)踱侣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)粪小,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人抡句,你說(shuō)我怎么就攤上這事探膊。” “怎么了待榔?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵逞壁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锐锣,道長(zhǎng)腌闯,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任雕憔,我火速辦了婚禮姿骏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘斤彼。我一直安慰自己分瘦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布琉苇。 她就那樣靜靜地躺著嘲玫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪并扇。 梳的紋絲不亂的頭發(fā)上去团,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音穷蛹,去河邊找鬼土陪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛俩莽,可吹牛的內(nèi)容都是我干的旺坠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼扮超,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼取刃!你這毒婦竟也來(lái)了蹋肮?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤璧疗,失蹤者是張志新(化名)和其女友劉穎坯辩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體崩侠,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漆魔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了却音。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片改抡。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖系瓢,靈堂內(nèi)的尸體忽然破棺而出阿纤,到底是詐尸還是另有隱情贯莺,我是刑警寧澤喉恋,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站衩茸,受9級(jí)特大地震影響骗绕,放射性物質(zhì)發(fā)生泄漏藐窄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一酬土、第九天 我趴在偏房一處隱蔽的房頂上張望荆忍。 院中可真熱鬧,春花似錦诺凡、人聲如沸东揣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至尔觉,卻和暖如春凉袱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侦铜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工专甩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钉稍。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓涤躲,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親贡未。 傳聞我的和親對(duì)象是個(gè)殘疾皇子种樱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容