Web Components - 面向未來(lái)的組件標(biāo)準(zhǔn)
首先需要說(shuō)明的是這不是一篇 Web Components 的科普文章,如果對(duì)此了解不多推薦先讀《A Guide to Web Components》。 有句古話-“授人以魚(yú),不如授人以漁”,如果把組件比作“魚(yú)”的話,對(duì)于前端開(kāi)發(fā)者而言,W3C組織制定的HTML標(biāo)準(zhǔn)以及瀏覽器廠商的實(shí)現(xiàn)都是“魚(yú)”而 不是“漁”,開(kāi)發(fā)者在需求無(wú)法滿(mǎn)足的情況下通過(guò)現(xiàn)有技術(shù)創(chuàng)造了各種組件,雖然短期滿(mǎn)足了需求但是由于嚴(yán)重缺乏標(biāo)準(zhǔn),導(dǎo)致同一個(gè)組件有成千上萬(wàn)的相似實(shí)現(xiàn)但 它們卻無(wú)法相互重用,這很大程度上制約了組件化的***價(jià)值-重用,Web Components則在組件標(biāo)準(zhǔn)化方面向前邁了一大步。
現(xiàn)狀與困境
組件化給前端開(kāi)發(fā)帶來(lái)了極大的效率提升,組件化的UI框架也因此層出不窮,從EXTJs、YUI到 jQuery UI ,再到 Bootstrap、React、Ratchet、Ionic等等等等等等,幾乎每年都有很多新的UI框架冒出來(lái),它們或者借鑒或者顛覆其他已存在的框架。簡(jiǎn)單對(duì)比一下就會(huì)發(fā)現(xiàn)這些框架的很大一部分模塊在功能上是重合的,但也僅僅在功能層面重合,代碼層面確完全不兼容。
接下來(lái)選擇 jQuery UI、KendoUI 以及 Bootstrap 中的Dialog
組件從初始化、方法調(diào)用以及事件響應(yīng)方面進(jìn)行簡(jiǎn)單的對(duì)比。
jQuery UI
- // 初始化
- $( "#dialog" ).dialog({
- dialogClass: "no-close"
- });
- // 顯示
- $( ".selector" ).dialog({ show: { effect: "blind", duration: 800 } });
- // 關(guān)閉事件
- $( ".selector" ).on( "dialogclose", function (e, ui) {
- // do something...
- });
Kendo UI
- // 初始化
- $("#dialog").kendoWindow({
- actions: [ "Minimize", "Maximize" ]
- });
- // 顯示
- var dialog = $("#dialog").data("kendoWindow");
- dialog.open();
- // 關(guān)閉事件
- var dialog = $("#dialog").data("kendoWindow");
- dialog.bind("close", function (e) {
- // do something...
- });
Bootstrap
- // 初始化
- $('#myModal').modal({
- keyboard: false
- });
- // 顯示
- $('#myModal').modal('show');
- // 關(guān)閉事件
- $('#myModal').on('hidden.bs.modal', function (e) {
- // do something...
- });
簡(jiǎn)單對(duì)比可以發(fā)現(xiàn),幾乎完全相同的功能在接口層面完全不兼容,導(dǎo)致使用者從某個(gè)實(shí)現(xiàn)切換到另一個(gè)實(shí)現(xiàn)時(shí)需要非常高的成本,這就是目前Web組件化方面無(wú)序和缺乏標(biāo)準(zhǔn)的一個(gè)寫(xiě)照。
再來(lái)看目前瀏覽器“內(nèi)置”組件的現(xiàn)狀,由標(biāo)準(zhǔn)化組織建立 HTML4、HTML5 等各種標(biāo)準(zhǔn),瀏覽器廠商按照標(biāo)準(zhǔn)實(shí)現(xiàn)“內(nèi)置”組件并聲稱(chēng)兼容某某標(biāo)準(zhǔn),開(kāi)發(fā)者遵循標(biāo)準(zhǔn)來(lái)使用組件,使得代碼可以在不同的瀏覽器里通過(guò)相同的方式來(lái)使用組件。
以“內(nèi)置”組件video
來(lái)簡(jiǎn)單示例:
- // 初始化(直接寫(xiě)<video>標(biāo)簽或者通過(guò)javascript創(chuàng)建)
- var video = document.createElement('video');
- // 播放
- video.play();
- // 播放事件
- video.addEventListener("play", function () {
- // do something...
- }, false);
相比使用各種組件框架來(lái)說(shuō),“內(nèi)置”組件也是由不同的開(kāi)發(fā)者(瀏覽器廠商)開(kāi)發(fā),但是由于遵循了相同的標(biāo)準(zhǔn)使得“內(nèi)置”組件的使用在跨瀏覽器方面的成本大幅降低。
綜上所述,組件框架目前無(wú)序、缺乏標(biāo)準(zhǔn)以及低效復(fù)用方面的問(wèn)題需要通過(guò)組件標(biāo)準(zhǔn)化來(lái)解決,而Web Components則是標(biāo)準(zhǔn)化的一個(gè)很好的選擇。
面向未來(lái)的組件標(biāo)準(zhǔn)
Web Components 的出現(xiàn)給組件標(biāo)準(zhǔn)化帶來(lái)了很好的契機(jī):
- WEB組件目前仍然依靠各種類(lèi)似"Hack"的方式來(lái)模擬,模擬方式也各有不同,很難統(tǒng)一和標(biāo)準(zhǔn)化,而 Web Components 則直接提供了標(biāo)準(zhǔn)化的組件定義方式,這是組件標(biāo)準(zhǔn)化的基石,使得未來(lái)的組件能夠統(tǒng)一創(chuàng)建、方法調(diào)用、事件監(jiān)聽(tīng)、屬性訪問(wèn)等。
- 基于標(biāo)準(zhǔn)化的組件定義方式,我們便可以像W3C等標(biāo)準(zhǔn)組織一樣來(lái)定義組件標(biāo)準(zhǔn),無(wú)需再依賴(lài)、等待“內(nèi)置”組件,這也使得我們獲得了“漁”的能力。
以上述的例子為例,未來(lái)可能會(huì)有一小撮人成立某個(gè)組件標(biāo)準(zhǔn)化組織-X,X的職責(zé)就是根據(jù)WEB組件的使用現(xiàn)狀以及潛在的新需求來(lái)規(guī)范一個(gè)組件,包括組件的名稱(chēng)、方法、屬性、事件。
例如《Dialog規(guī)范1.0》
- 組件名:x-dialog
- 屬性:title
- 方法:show hide
- 事件:hide show
隨后出現(xiàn)的UI框架宣稱(chēng)支持《Dialog規(guī)范》,但在實(shí)現(xiàn)上完全沒(méi)有制約,可以是完全不同的實(shí)現(xiàn)方式、或者更好的性能、更炫的UI,而對(duì)于開(kāi)發(fā)者而言,只需要寫(xiě)如下代碼即可:
- // 初始化(<x-dialog/>或者如下代碼)
- var dialog = document.createElement('x-dialog');
- // 獲取和設(shè)置title
- var title = dialog.title;
- dialog.title = title + '-_-';
- // 顯示
- dialog.show();
- // 關(guān)閉事件
- dialog.addEventListener('hide', function( e ) {
- // do something...
- }, false);
當(dāng)用戶(hù)不滿(mǎn)意某個(gè) Dialog 的實(shí)現(xiàn)而需要切換到其他實(shí)現(xiàn)版本時(shí)只需要引入不同的實(shí)現(xiàn)庫(kù),而不再需要重構(gòu)代碼。
跨端的組件標(biāo)準(zhǔn)
集鵠在跨端組件實(shí)踐 - 移動(dòng)時(shí)代的前端一文中提到了跨端組件的概念。
跨端組件的實(shí)現(xiàn)同樣面臨著標(biāo)準(zhǔn)化的問(wèn)題,Web Components 的標(biāo)準(zhǔn)化只規(guī)范接口,而底層的實(shí)現(xiàn)是完全自由的,自由到你可以使用 Web 技術(shù)來(lái)實(shí)現(xiàn)也可以使用 Native技術(shù)。
同樣以 Dialog 為例,開(kāi)發(fā)者可以在 Android 中用 Java 或者在 iOS 中用 Objective C 來(lái)開(kāi)發(fā)聲稱(chēng)兼容 《Dialog規(guī)范1.0》的組件,此時(shí),Web 開(kāi)發(fā)者的那段調(diào)用 Dialog 的代碼不僅僅在 瀏覽器環(huán)境有效,在 Native 依然有效,而且調(diào)用的是 Native 實(shí)現(xiàn),能夠獲得更為出色的性能。
總結(jié)
回顧瀏覽器的發(fā)展歷史,也曾經(jīng)歷混亂和無(wú)序,隨著W3C標(biāo)準(zhǔn)化組織的出現(xiàn)這一局面有了翻天覆地的變化,而對(duì)于Web組件而言,Web Components 的出現(xiàn)才僅僅是這一變化的開(kāi)始,隨著更為復(fù)雜的多端環(huán)境的出現(xiàn),組件標(biāo)準(zhǔn)化還有著更大的想象空間。