Web components API: Shadow DOM判族、Light DOM、 Lifecycle Events 和 Custom Events

shadow DOM

組件開發(fā)者編寫的 DOM项戴。Shadow DOM 對(duì)組件來說是本地的形帮,它定義了它的內(nèi)部結(jié)構(gòu)、作用域 CSS周叮,并封裝了實(shí)現(xiàn)細(xì)節(jié)辩撑。它還可以定義如何呈現(xiàn)由組件的使用者編寫的 DOM。

light DOM

由組件使用者編寫的 DOM仿耽。這個(gè) DOM 存在于組件的 shadow DOM 之外合冀。它是自定義元素的實(shí)際子元素。特別是 slot项贺。

插槽允許組件使用者定義 html君躺,因?yàn)椴皇?shadow DOM 的一部分,沒有被封裝开缎,所以樣式受頁面的影響棕叫,并且 DOM 可以被獲取到。比如下面 img 和 span 就是 light DOM:

<webc-button>
  <img src slot="icon" />
  <span> Hello </span>
</webc-button>

Lifecycle Events

一圖勝千言

image.png

Constructor

創(chuàng)建 webc 時(shí)調(diào)用奕删。

  1. HTMLElement 類建立原型鏈的地方
  2. 初始化組件必要的屬性
  3. 使用 attachShadow() 方法創(chuàng)建 shadow DOM

其余操作俺泣,比如獲取數(shù)據(jù)、渲染不建議在這里完残,而是在 connectedCallback 中

connectedCallback

每次 web 組件連接到 DOM 時(shí)調(diào)用伏钠。適合獲取數(shù)據(jù)或添加事件監(jiān)聽器。

adoptedCallback

每次將 Web 組件移動(dòng)到新文檔時(shí)調(diào)用谨设。這特別適用于 iFrame熟掂。

attributeChangedCallback

每次添加、更改或刪除 web 組件的屬性時(shí)調(diào)用铝宵。

接收三個(gè)參數(shù):

  1. 屬性名
  2. 舊值
  3. 新值
attributeChangedCallback(name, oldValue, newValue) {

}

要能夠監(jiān)聽到屬性的變化打掘,需要 observedAttributes 方法指定要監(jiān)聽的屬性。

static get observedAttributes() {

  return ['value', 'min', 'max'];

}

disconnectedCallback

Web 組件與文檔 DOM 斷開連接時(shí)調(diào)用鹏秋。適合移除事件監(jiān)聽器尊蚁,中斷數(shù)據(jù)的請(qǐng)求等操作。

Custom Events

當(dāng)我們基于用戶操作執(zhí)行代碼時(shí)侣夷,原生事件是我們必須在 Web 上添加交互性的主要方式:例如横朋,當(dāng)用戶單擊某處(單擊事件)時(shí)我們運(yùn)行一些程序,或者當(dāng)用戶輸入時(shí)驗(yàn)證值的合法性百拓。

同樣的琴锭,在開發(fā) web 組件時(shí)晰甚,不得不需要用到事件。因?yàn)椋菏录墙M建公共 API 的一部分决帖,某些事件觸發(fā)后的邏輯需要交給組件使用者處理厕九。比如:

  1. 什么時(shí)候加載完數(shù)據(jù)
  2. 值更改
  3. 內(nèi)部觸發(fā)的事件

創(chuàng)建自定義事件

使用 Event 構(gòu)造函數(shù)

const event = new Event('build')

ele.addEventListener('build', function (e) { ... }, false)
ele.dispatchEvent(event)

添加自定義數(shù)據(jù)

要向事件對(duì)象添加更多數(shù)據(jù),使用 customEvent地回,detail 屬性可用于傳遞自定義數(shù)據(jù)扁远。 例如:

const event = new CustomEvent('build', { 'detail': 22 })

ele.dispatchEvent(event)

組件庫建設(shè)

內(nèi)部使用純?cè)?API 搞了一套移動(dòng)端組件庫。大致羅列下一套組件庫需要做哪些工作:

布局適配刻像、主題

目前主流的組件庫在適配上基本采用的方式是:設(shè)置基準(zhǔn)值畅买,然后使用 rem 或 vw 或者兩者兼用的方式,開發(fā)時(shí)同時(shí)使用 px细睡,打包時(shí)使用 px2rem 的插件進(jìn)行處理谷羞。但是 webc 組件不同,css 被封裝到了 Shadow DOM 中溜徙,無法使用 px2rem 進(jìn)行修改湃缎。并且 webc 組件還要面臨使用者適配方案不一致的情況。

webc 適配方案

既然 webcomponents 的組件是已經(jīng)打包成了不可見的 shadow dom 了萌京,既然通過插件改不了 css 代碼雁歌,就需要一個(gè)變量和外部形成橋梁宏浩,css 變量就是低成本知残、便捷的選擇。事實(shí)上已經(jīng)有不少三方組件庫采用 css 變量實(shí)現(xiàn)主題的自定義比庄。

;(function (win) {
  win.rwcFn = function () {
    var oDoc = document.documentElement,
      iW = oDoc.clientWidth || win.innerWidth,
      _base = 375,
      _maxW = 1024

    iW = Math.min(iW, _maxW)

    oDoc.style.setProperty('--webc-base-font', (iW / _base).toFixed(2))
  }

  rwcFn()

  win.addEventListener('resize', rwcFn, false)
})(window)
@media (min-width: 320px) {
  :root {
    --webc-base-font: 0.8533333333333334;
  }
}

@media (min-width: 360px) {
  :root {
    --webc-base-font: 0.96;
  }
}

/*
    iphone 678x
 */

@media (min-width: 375px) {
  :root {
    --webc-base-font: 1;
  }
}

/*
    iphone 678 plus
 */
@media (min-width: 414px) {
  :root {
    --webc-base-font: 1.104;
  }
}

/*
   ipad  
 */
@media (min-width: 677px) {
  :root {
    --webc-base-font: 1.8053333333333332;
  }
}

/*
   ipad  
 */
@media (min-width: 712px) {
  :root {
    --webc-base-font: 1.8986666666666667;
  }
}

/*
   ipad  
 */
@media (min-width: 768px) {
  :root {
    --webc-base-font: 2.048;
  }
}

代碼質(zhì)量

eslint求妹、prettier、husky

無障礙

無障礙

單元測(cè)試

使用 @open-wc/testing 和 @web/test-runner 做單元測(cè)試

與 Vue & React 結(jié)合

React 與 Web Components

Vue 與 Web Components

打包構(gòu)建

使用 webpack

打包出一個(gè)全局 bundle佳窑,針對(duì)每個(gè)組件打包出一個(gè)單獨(dú)的包制恍,按需加載時(shí)只引入單獨(dú)的文件即可。

文檔建設(shè)

構(gòu)建部署

stencil

純?cè)_發(fā)存在不少問題神凑,

  1. 開發(fā)效率低下净神;比如 html 模版和樣式的編寫和維護(hù)、數(shù)據(jù)更新的讀取和監(jiān)聽溉委、事件的觸發(fā)鹃唯、slot 的監(jiān)聽等
  2. 整體架構(gòu)需要從 0 到 1 搭建
  3. 目標(biāo)文件的輸出
  4. 與其他框架的集成等諸多問題

stencil 是由 ionic 團(tuán)隊(duì)開發(fā)的用于開發(fā) web 組件庫的工具鏈,包括:框架集成瓣喊、靜態(tài)站點(diǎn)生成坡慌、單元測(cè)試等功能。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末藻三,一起剝皮案震驚了整個(gè)濱河市洪橘,隨后出現(xiàn)的幾起案子跪者,更是在濱河造成了極大的恐慌,老刑警劉巖熄求,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渣玲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡弟晚,警方通過查閱死者的電腦和手機(jī)柜蜈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來指巡,“玉大人淑履,你說我怎么就攤上這事≡逖” “怎么了秘噪?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勉耀。 經(jīng)常有香客問我指煎,道長,這世上最難降的妖魔是什么便斥? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任至壤,我火速辦了婚禮,結(jié)果婚禮上枢纠,老公的妹妹穿的比我還像新娘像街。我一直安慰自己,他們只是感情好晋渺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布镰绎。 她就那樣靜靜地躺著,像睡著了一般木西。 火紅的嫁衣襯著肌膚如雪畴栖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天八千,我揣著相機(jī)與錄音吗讶,去河邊找鬼。 笑死恋捆,一個(gè)胖子當(dāng)著我的面吹牛照皆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸠信,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纵寝,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起爽茴,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤葬凳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后室奏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體火焰,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年胧沫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昌简。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绒怨,死狀恐怖纯赎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情南蹂,我是刑警寧澤犬金,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站六剥,受9級(jí)特大地震影響晚顷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜疗疟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一该默、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧策彤,春花似錦栓袖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至必搞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間囊咏,已是汗流浹背恕洲。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梅割,地道東北人霜第。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像户辞,于是被迫代替她去往敵國和親泌类。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

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

  • 前言 在初涉前端之時(shí)底燎,我就一直在好奇一個(gè)問題刃榨,為什么像: …… 等等這些標(biāo)簽弹砚,看起來似乎很簡單,可為什么可以展現(xiàn)出...
    隱逸王閱讀 424評(píng)論 0 0
  • 這是webkitBlog上一篇文章的翻譯枢希,原文鏈接桌吃。 很高興宣布我們已經(jīng)對(duì)slot-base Shadow DOM...
    IAIAE閱讀 2,479評(píng)論 0 2
  • 組件化是前端工程化重要的一環(huán),UI 和 交互(或邏輯)的復(fù)用極大的提高開發(fā)效率以及減少代碼冗余苞轿。 目前開源的組件庫...
    一蓑煙雨任平生_cui閱讀 4,519評(píng)論 0 4
  • 前端組件化其實(shí)是個(gè)持續(xù)了很長時(shí)間的過程了茅诱,從最開始的jquery的插件開始。我們就在封裝一些js搬卒,css瑟俭,html...
    潘逸飛閱讀 9,805評(píng)論 1 16
  • 組件的概念 組件,是數(shù)據(jù)和方法的一個(gè)封裝契邀,其定義了一個(gè)可重用的軟件元素的功能尔当,展示和使用,通常表現(xiàn)為一個(gè)或一組可重...
    zx_lau閱讀 2,438評(píng)論 0 3