Web Components 原生元件 Trends

Jason_X發表於2019-02-28

在現在前端元件化開發大行其道的今天,各種Framework讓人眼花繚亂,同一個公司,不同團隊,可能使用的是不同的框架。那麼在統一視覺,互動,功能上,不同的框架可以都需要用不同的框架開發一遍,但是在功能和互動有所改變的時候,又需要全部同步開發一次。這種對人力和物力都是一種消耗,而且維護性也不是很好,那麼有沒有一種元件可以相容所有的框架,並且開發和維護方便呢?那麼Web Components可能就是你需要的答案。

Web Components是原生提供的一種技術,他允許建立可重用的定製元素。

概念

Web Components 是原生提供的一種技術,可以自定義UI控制元件。Web Components由四項技術組成。

  • Custom elements(自定義元素)
  • Shadow DOM(影子DOM)
  • HTML templates(HTML模板)
  • HTML Imports(HTML匯入)
  1. Custom elements
    一組javascript API,允許你定義custom element及其行為。
customElements.define(`jason-custom`,
  class extends HTMLElement {
    constructor() {
      super()

      let jasonTestElem = document.createElement(`div`);
      jasonTestElem.textContent = this.getAttribute(`text`);

      let shadowRoot = this.attachShadow({mode: `open`})
        .appendChild(jasonTestElem)
  }
})
複製程式碼

使用CustomElementRegistry物件來生成custom elements,該物件允許你註冊一個custom element

customElements.define()接受三個引數:

  • DOMString 建立元素的名稱(custom element名稱中必須包含短橫線);
  • 類物件 定於類的行為;
  • 一個包含extends屬性的物件,可選引數,指定建立的元素繼承自哪個內建元素。

custom elment共有兩種:

  • Autonomous custom elements
    是一種獨立元素,他不繼承任何一種HTML元素,你可以在頁面中直接使用它,比如<jason-elm></jason-elm>, 或者document.createElement(`jason-elm`)
  • Customized built-in elements 繼承基本的HTML元素,建立時,你必須要繼承自某個基本的HTML元素,使用的時候需在基本元素中通過is屬性指定名稱。比如<p is=`jason-elm`></p>, 或者document.createElement(`p`, { is: `jason-elm`})

例子:

Autonomous custom elements

class JasonCustom extends HTMLElement {
    constructor() {
        super()
        
        let divElem = document.createElement(`div`)
        divElem.textContent = `This is a test Autonomous custom element`
        
        let shadowRoot = this.attachShadow({mode: `open`})
        shadowRoot.appendChild(divElem)
    }
}
customElements.define(`jason-custom`, JasonCustom)
複製程式碼

那麼我們就可以在頁面中使用他了<jason-custom />

Customized built-in elements

class JasonCustom extends HTMLUListElement {
    construtor() {
        super()
        //
    }
}

customElements.define(`jason-custom`, JasonCustom, { extends: `ul` })
複製程式碼

在頁面中使用這種自定義的元素使用
<ul is=`jason-custom` />

自定義元件的生命週期回撥函式

  • connectedCallback: 當custom element 首次被插入文件DOM時,被呼叫。
  • disconnectedCallback: 當 custom element從文件DOM中刪除時,被呼叫。
  • adoptedCallback: 當 custom element被移動到新的文件時,被呼叫。
  • attributesChangedCallback: 當 custom element增加、刪除、修改自身屬性時,被呼叫。

使用宣告週期回撥函式的例子可以線上看life-cycle-callbacks

Shadow DOM

Web components 一個重要特性就是封裝,他可以將HTML, CSS,和行為隱藏起來,並從頁面上的其他程式碼分開起來,這樣不用的功能就不會混在一起。那麼就是要介紹的Shadow DOM, shadow DOM可以將隱藏的獨立的元素新增到一個元素上。

Shadow DOM允許將隱藏的DOM新增到常規的DOM樹中

Shadow DOM
Web Components 原生元件 Trends

Shadow DOM 有幾個概念

  • Shadow host: 一個常規 DOM節點,Shadow DOM會被新增到這個節點上。
  • Shadow tree:Shadow DOM內部的DOM樹。
  • Shadow boundary:Shadow DOM結束的地方,也是常規 DOM開始的地方。
  • Shadow root: Shadow tree的根節點。

你可以像操作基本的DOM元素一樣操作Shadow DOM元素,你也可以給Shadow DOM新增<style>而且隻影響Shadow DOM裡的元素。Shadow DOM的標準意味著你可以為自己的元素維護一組Shadow DOM。

用法

可以使用Element.attachShadow()來為任意一個元素新增Shoadow DOM,attachShadow裡接受一個物件作為引數,引數有個屬性mode,有兩個可選值open close

let shadowOpen = Elementp.attachShadow({`mode`: open})
let shadowClose = Elementp.attachShadow({`mode`: close})
複製程式碼

open 可以通過javascript來獲取shandow DOM 例如

let shadowDom = Elementp.shadowRoot
複製程式碼

close的話,就是不可以在外部獲取到shadow Dom 了,訪問shadowRoot就會返回null

更具體的文章請檢視
Open vs. Closed Shadow DOM(有可能需要科學上網)

templates slot

對的,沒有錯,現在原生提供了模板的功能!!這種模板不會被瀏覽器渲染但是可以使用javascript呼叫!

官方例子

<template id="my-paragraph">
  <p>My paragraph</p>
</template>
複製程式碼

使用的時候怎麼用呢

let template = document.getElementById(`my-paragraph`);
let templateContent = template.content;
document.body.appendChild(templateContent);
複製程式碼

你可以用slot 增加template的靈活度,slot的作用是用來提供一個佔位的

slot使用 name 屬性作為id, 你能在tempalte 中定義任意的 html 片斷作為佔位符,在模板物件被使用在html 指令碼中時。
例如:

// tamplate
<p><slot name="my-text">My default text</slot></p>

// 使用時
<my-paragraph>
  <span slot="my-text">Let`s have some different text!</span>
</my-paragraph>

//生成的html
<p><span>Let`s have some different text!</span></p>
複製程式碼

當然上面這些程式碼都算是農耕時代的程式碼,那麼可以讓我們用工業2.0的效率來開發web Components 元件的框架有Google的polymer,ionic 自己的stencil

雖然這個標準好久就出現了,但是其實一直沒有很多的開發者介入。可能源於這玩意的相容性。

Web Components 原生元件 Trends

可以看到除了chrome高版本和safari是支援最完全的。但是這玩意多好玩的啊,可以拿來做實驗性的產品來玩玩多好!

Stay Hungry. Stay Foolish

Web Components 原生元件 Trends

相關文章