久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

致我們終將組件化的Web

 文質(zhì)君 2016-03-14

原文出處: AlloyTeam 歡迎分享原創(chuàng)到伯樂(lè)頭條

《=》

”按模塊劃分“目錄結(jié)構(gòu),,把當(dāng)前模塊下的所有邏輯和資源都放一起了,,這對(duì)于多人獨(dú)自開(kāi)發(fā)和維護(hù)個(gè)人模塊不是很好嗎?當(dāng)然了,那爭(zhēng)論的結(jié)果是我乖乖地改回主流的”按資源劃分“的目錄結(jié)構(gòu),。因?yàn)?,沒(méi)有做到JS模塊化和資源模塊化,僅僅物理位置上的模塊劃分是沒(méi)有意義的,,只會(huì)增加構(gòu)建的成本而已,。

雖然他說(shuō)得好有道理我無(wú)言以對(duì),但是我心不甘,,等待他日前端組件化成熟了,,再來(lái)一戰(zhàn)!

而今天就是我重申正義的日子,!只是當(dāng)年那個(gè)跟你撕逼的人不在,。

模塊化的不足

模塊一般指能夠獨(dú)立拆分且通用的代碼單元。由于JavaScript語(yǔ)言本身沒(méi)有內(nèi)置的模塊機(jī)制(ES6有了?。,。覀円话銜?huì)使用CMD或ADM建立起模塊機(jī)制?,F(xiàn)在大部分稍微大型一點(diǎn)的項(xiàng)目,,都會(huì)使用requirejs或者seajs來(lái)實(shí)現(xiàn)JS的模塊化。多人分工合作開(kāi)發(fā),,其各自定義依賴和暴露接口,,維護(hù)功能模塊間獨(dú)立性,對(duì)于項(xiàng)目的開(kāi)發(fā)效率和項(xiàng)目后期擴(kuò)展和維護(hù),,都是是有很大的幫助作用,。

但,麻煩大家稍微略讀一下下面的代碼

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

require([

'Tmpl!../tmpl/list.html','lib/qqapi','module/position','module/refresh','module/page','module/net'

], function(listTmpl, QQapi, Position, Refresh, Page, NET){

var foo = '',

bar = [];

QQapi.report();

Position.getLocaiton(function(data){

//...

});

var init = function(){

bind();

NET.get('/cgi-bin/xxx/xxx',function(data){

renderA(data.banner);

renderB(data.list);

});

};

var processData = function(){

};

var bind = function(){

};

var renderA = function(){

};

var renderB = function(data){

listTmpl.render('#listContent',processData(data));

};

var refresh = function(){

Page.refresh();

};

// app start

init();

});

上面是具體某個(gè)頁(yè)面的主js,,已經(jīng)封裝了像Position,,NET,Refresh等功能模塊,,但頁(yè)面的主邏輯依舊是”面向過(guò)程“的代碼結(jié)構(gòu),。所謂面向過(guò)程,是指根據(jù)頁(yè)面的渲染過(guò)程來(lái)編寫(xiě)代碼結(jié)構(gòu),。像:init -> getData -> processData -> bindevent -> report -> xxx ,。 方法之間線性跳轉(zhuǎn),你大概也能感受這樣代碼弊端,。隨著頁(yè)面邏輯越來(lái)越復(fù)雜,,這條”過(guò)程線“也會(huì)越來(lái)越長(zhǎng),并且越來(lái)越繞,。加之缺少規(guī)范約束,,其他項(xiàng)目成員根據(jù)各自需要,,在”過(guò)程線“加插各自邏輯,最終這個(gè)頁(yè)面的邏輯變得難以維護(hù),。

開(kāi)發(fā)需要小心翼翼,,生怕影響“過(guò)程線”后面正常邏輯。并且每一次加插或修改都是bug泛濫,,無(wú)不令產(chǎn)品相關(guān)人員個(gè)個(gè)提心吊膽,。

頁(yè)面結(jié)構(gòu)模塊化

基于上面的面向過(guò)程的問(wèn)題,行業(yè)內(nèi)也有不少解決方案,,而我們團(tuán)隊(duì)也總結(jié)出一套成熟的解決方案:Abstractjs,,頁(yè)面結(jié)構(gòu)模塊化。我們可以把我們的頁(yè)面想象為一個(gè)樂(lè)高機(jī)器人,,需要不同零件組裝,如下圖,,假設(shè)頁(yè)面劃分為tabContainer,,listContainer和imgsContainer三個(gè)模塊。最終把這些模塊add到最終的pageModel里面,,最終使用rock方法讓頁(yè)面啟動(dòng)起來(lái),。


(原過(guò)程線示例圖)


(頁(yè)面結(jié)構(gòu)化示例圖)

下面是偽代碼的實(shí)現(xiàn)

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

require([

'Tmpl!../tmpl/list.html','Tmpl!../tmpl/imgs.html','lib/qqapi','module/refresh','module/page'

], function(listTmpl, imgsTmpl, QQapi, Refresh, Page ){


var tabContainer = new RenderModel({

renderContainer: '#tabWrap',

data: {},

renderTmpl: '

  • {{item}}
  • ',

    event: function(){

    // tab's event

    }

    });


    var listContainer = new ScrollModel({

    scrollEl: $.os.ios ? $('#Page') : window,

    renderContainer: '#listWrap',

    renderTmpl: listTmpl,

    cgiName: '/cgi-bin/index-list?num=1',

    processData: function(data) {

    //...

    },

    event: function(){

    // listElement's event

    },

    error: function(data) {

    Page.show('數(shù)據(jù)返回異常[' + data.retcode + ']');

    }

    });


    var imgsContainer = new renderModel({

    renderContainer: '#imgsWrap',

    renderTmpl: listTmpl,

    cgiName: '/cgi-bin/getPics',

    processData: function(data) {

    //...

    },

    event: function(){

    // imgsElement's event

    },

    complete: function(data) {

    QQapi.report();

    }

    });


    var page = new PageModel();

    page.add([tabContainer,listContainer,imgsContainer]);

    page.rock();


    });

    我們把這些常用的請(qǐng)求CGI,處理數(shù)據(jù),,事件綁定,,上報(bào),容錯(cuò)處理等一系列邏輯方法,,以頁(yè)面塊為單位封裝成一個(gè)Model模塊,。

    這樣的一個(gè)抽象層Model,我們可以清晰地看到該頁(yè)面塊,,請(qǐng)求的CGI是什么,,綁定了什么事件,做了什么上報(bào),,出錯(cuò)怎么處理,。新增的代碼就應(yīng)該放置在相應(yīng)的模塊上相應(yīng)的狀態(tài)方法(preload,process,,event,,complete…),杜絕了以往的無(wú)規(guī)則亂增代碼的行文,。并且,,根據(jù)不同業(yè)務(wù)邏輯封裝不同類型的Model,如列表滾動(dòng)的ScrollModel,,滑塊功能的SliderModel等等,,可以進(jìn)行高度封裝,集中優(yōu)化。

    現(xiàn)在基于Model的頁(yè)面結(jié)構(gòu)開(kāi)發(fā),,已經(jīng)帶有一點(diǎn)”組件化“的味道,。每個(gè)Model都帶有各自的數(shù)據(jù),模板,,邏輯,。已經(jīng)算是一個(gè)完整的功能單元。但距離真正的WebComponent還是有一段距離,,至少滿足不了我的”理想目錄結(jié)構(gòu)“,。

    WebComponents 標(biāo)準(zhǔn)

    我們回顧一下使用一個(gè)datapicker的jquery的插件,所需要的步奏:

    1. 引入插件js

    2. 引入插件所需的css(如果有)

    3. copy 組件的所需的html片段

    4. 添加代碼觸發(fā)組件啟動(dòng)

    現(xiàn)階段的“組件”基本上只能達(dá)到是某個(gè)功能單元上的集合,。他的資源都是松散地分散在三種資源文件中,,而且組件作用域暴露在全局作用域下,缺乏內(nèi)聚性很容易就會(huì)跟其他組件產(chǎn)生沖突,,如最簡(jiǎn)單的css命名沖突,。對(duì)于這種“組件”,還不如上面的頁(yè)面結(jié)構(gòu)模塊化,。

    于是W3C按耐不住了,,制定一個(gè)WebComponents標(biāo)準(zhǔn),為組件化的未來(lái)指引了明路,。

    下面以較為簡(jiǎn)潔的方式介紹這份標(biāo)準(zhǔn),,力求大家能夠快速了解實(shí)現(xiàn)組件化的內(nèi)容。(對(duì)這部分了解的同學(xué),,可以跳過(guò)這一小節(jié))

    1.

    模板這東西大家最熟悉不過(guò)了,,前些年見(jiàn)的較多的模板性能大戰(zhàn)artTemplate,juicer,,tmpl,,underscoretemplate等等。而現(xiàn)在又有mustachejs無(wú)邏輯模板引擎等新入選手,??墒谴蠹矣袥](méi)有想過(guò),這么基礎(chǔ)的能力,,原生HTML5是不支持的(T_T),。

    而今天WebComponent將要提供原生的模板能力

    XHTML

    1

    2

    3

    id='datapcikerTmpl'>

    我是原生的模板

    template標(biāo)簽內(nèi)定義了myTmpl的模板,需要使用的時(shí)候就要innerHTML= document.querySelector('#myTmpl').content,;可以看出這個(gè)原生的模板夠原始,,模板占位符等功能都沒(méi)有,對(duì)于動(dòng)態(tài)數(shù)據(jù)渲染模板能力只能自力更新,。

    2. ShadowDom 封裝組件獨(dú)立的內(nèi)部結(jié)構(gòu)

    ShadowDom可以理解為一份有獨(dú)立作用域的html片段,。這些html片段的CSS環(huán)境和主文檔隔離的,,各自保持內(nèi)部的獨(dú)立性。也正是ShadowDom的獨(dú)立特性,,使得組件化成為了可能,。

    JavaScript

    1

    2

    3

    var wrap = document.querySelector('#wrap');

    var shadow = wrap.createShadowRoot();

    shadow.innerHTML = '

    you can not see me

    '

    在具體dom節(jié)點(diǎn)上使用createShadowRoot方法即可生成其ShadowDom。就像在整份Html的屋子里面,,新建了一個(gè)shadow的房間,。房間外的人都不知道房間內(nèi)有什么,保持shadowDom的獨(dú)立性,。

    3. 自定義原生標(biāo)簽

    初次接觸Angularjs的directive指令功能,,設(shè)定好組件的邏輯后,一個(gè)就能引入整個(gè)組件,。如此狂炫酷炸碉堡天的功能,,實(shí)在令人拍手稱快,躍地三尺,。

    JavaScript

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    var tmpl = document.querySelector('#datapickerTmpl');

    var datapickerProto = Object.create(HTMLElement.prototype);


    // 設(shè)置把我們模板內(nèi)容我們的shadowDom

    datapickerProto.createdCallback = function() {

    var root = this.createShadowRoot();

    root.appendChild(document.importNode(tmpl.content, true));

    };


    var datapicker = docuemnt.registerElement('datapicker',{

    prototype: datapickerProto

    });

    Object.create方式繼承HTMLElement.prototype,,得到一個(gè)新的prototype。當(dāng)解析器發(fā)現(xiàn)我們?cè)谖臋n中標(biāo)記它將檢查是否一個(gè)名為createdCallback的方法,。如果找到這個(gè)方法它將立即運(yùn)行它,所以我們把克隆模板的內(nèi)容來(lái)創(chuàng)建的ShadowDom,。

    最后,,registerElement的方法傳遞我們的prototype來(lái)注冊(cè)自定義標(biāo)簽。

    上面的代碼開(kāi)始略顯復(fù)雜了,,把前面兩個(gè)能力“模板”“shadowDom”結(jié)合,,形成組件的內(nèi)部邏輯。最后通過(guò)registerElement的方式注冊(cè)組件,。之后可以愉快地的使用,。

    4. imports解決組件間的依賴

    XHTML

    1

    rel='import' href='datapciker.html'>

    這個(gè)類php最常用的html導(dǎo)入功能,HTML原生也能支持了,。

    WebComponents標(biāo)準(zhǔn)內(nèi)容大概到這里,,是的,我這里沒(méi)有什么Demo,,也沒(méi)有實(shí)踐經(jīng)驗(yàn)分享,。由于webComponents新特性,基本上除了高版本的Chrome支持外,,其他瀏覽器的支持度甚少,。雖然有polymer幫忙推動(dòng)webcompoents的庫(kù)存在,但是polymer自身的要求版本也是非常高(IE10+),。所以今天的主角并不是他,。

    我們簡(jiǎn)單來(lái)回顧一下WebCompoents的四部分功能:

    1 .

      本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
      轉(zhuǎn)藏 分享 獻(xiàn)花(0

      0條評(píng)論

      發(fā)表

      請(qǐng)遵守用戶 評(píng)論公約

      類似文章 更多