自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

看了Quark Design后,我去深入了解了Web Components

開發(fā) 前端
現(xiàn)今前端生態(tài)中框架層出不窮,在生產(chǎn)中為了提升效率和標準化組件,就會針對框架開發(fā)組件庫。但是各種框架之間是不兼容的,對此需要對應(yīng)開發(fā)適應(yīng)框架的組件庫,這樣也造成維護成本攀升。就如同物理界有電磁相互作用、強相互作用以及弱相互作用,需要單獨的物理理論來解釋這三種作用造成的物理現(xiàn)象,這樣讓眾多物理學(xué)家在朝著大統(tǒng)一理論前進,而Web Components可以看作是現(xiàn)今UI組件庫"大統(tǒng)一理論"的一種解決方案。

?1.寫在前面

最近哈啰單車前端團隊開源的Quark Design組件庫,號稱是下一代前端組件庫,可以同時在任意框架或無框架中使用。

那么,什么是Web Components?

2.什么是Web Components?

現(xiàn)今前端生態(tài)中框架層出不窮,在生產(chǎn)中為了提升效率和標準化組件,就會針對框架開發(fā)組件庫。但是各種框架之間是不兼容的,對此需要對應(yīng)開發(fā)適應(yīng)框架的組件庫,這樣也造成維護成本攀升。就如同物理界有電磁相互作用、強相互作用以及弱相互作用,需要單獨的物理理論來解釋這三種作用造成的物理現(xiàn)象,這樣讓眾多物理學(xué)家在朝著大統(tǒng)一理論前進,而Web Components可以看作是現(xiàn)今UI組件庫"大統(tǒng)一理論"的一種解決方案。

圖片

Web Components與React、Vue?等框架中的組件類似,其實在Vue中也采用了很多基于Web Components?的設(shè)計。這是一個可復(fù)用的UI構(gòu)建模塊,封裝了所有渲染所需要的HTML、CSS?以及基于Javascript?的邏輯。最大的區(qū)別是,它不依賴于特定的JavaScript框架,而是利用瀏覽器原生提供的技術(shù),這樣你的Web組件就與框架無關(guān)了。

3.Web Components的主要內(nèi)容

Web Components的主要內(nèi)容如下:

  • Custom Elements?:原生提供的API,用于可自定義Custom Elements和行為。
  • Shadow DOM:原生提供的API,用于封裝與主文檔DOM隔離的私有DOM,不受外部DOM的樣式和行為的影響。
  • Templates:
  • Attributes:
  • Slots:
  • Life cycle methods:

接下來,跟隨我的腳步在例子中逐個實現(xiàn)這些概念,逐個擊破理論。

4.Custom Elements

Custom Elements是Web Components?中的一個重要特性,可以提供給開發(fā)者將html的功能封裝為自定義標簽,方便進行復(fù)用。也就是說,Custom Elements?本質(zhì)上是用戶用于實現(xiàn)在html?中有效使用的,類似<div>、<button>?等自定義標簽。最大區(qū)別在于,自定義標簽有著自己的模板、行為和標簽名稱,通過Javascript的API實現(xiàn)的。

Custom Elements?總是使用連字符-?進行自定義標簽的標識,即<one-button/>?,各大瀏覽器公司達成公司不在創(chuàng)建任何新的標簽元素,來防止元素沖突。熟悉vue框架的開發(fā)者應(yīng)該知道,在vue中的自定義組件命令有<OneButton/>或<one-button/>?這種結(jié)構(gòu),官方推薦的是<one-button/>這種使用方式。

通過customElements.define來簡單注冊自定義組件,下面就來簡單實踐下:

// one-button.js
// 1、創(chuàng)建自定義組件的類
class OneButton extends HTMLElement{
constructor(){
super()
// 2、創(chuàng)建組件內(nèi)容
this.innerHTML = `<button>hello onechuan</button>`
}
}

// 3、進行自定義組件的注冊
customElements.define("one-button", OneButton)

// index.html
// 4、html中進行使用
<one-button></one-button>
<script src="./one-button.js"></script>

運行展示:

圖片

5.Shadow DOM

Shadow DOM?與原生DOM的區(qū)別就是用戶自定義封裝的DOM,本質(zhì)上還是DOM元素。不同的是,Shadow DOM?可以將自定義的DOM片段與其他DOM進行隔離,可以實現(xiàn)樣式不受外部DOM的影響,類似于使用iframe?內(nèi)嵌了一個html。也正是Shadow DOM的存在,能夠進行DOM隔離、實現(xiàn)獨立的組件王國,使得自定義組件跨域框架的約束,不再耦合,確保在任何無框架和任何框架中正常使用。

如圖所示:

圖片

圖示來自MDN文檔

一些 Shadow DOM 特有的術(shù)語:

  • Shadow host:一個常規(guī) DOM 節(jié)點,Shadow DOM 會被附加到這個節(jié)點上。
  • Shadow tree:Shadow DOM 內(nèi)部的 DOM 樹。
  • Shadow boundary:Shadow DOM 結(jié)束的地方,也是常規(guī) DOM 開始的地方。
  • Shadow root: Shadow tree 的根節(jié)點。

Shadow DOM ?并不是新生事物,在原生<video>?標簽中其實就有內(nèi)置的Shadow DOM ?,包含一系列的按鈕和其他控制器等。而Web Components?只不過是允許用戶根據(jù)需要使用Shadow DOM來實現(xiàn)自定義標簽。

那么,就接著上面的例子一起來實現(xiàn)下:

// one-button.js
// 1、創(chuàng)建自定義組件的類
class OneButton extends HTMLElement{
constructor(){
super()
// 2、創(chuàng)建shadow dom
this.attachShadow({mode: 'open'})
this.shadowRoot.innerHTML = `<button>hello onechuan</button>`
}
}

// 3、進行自定義組件的注冊
customElements.define("one-button", OneButton)

運行得到:

圖片

在上面運行結(jié)果中,實現(xiàn)的展示效果是一樣,但是渲染的dom節(jié)點卻有所不同,在使用shadow dom?實現(xiàn)的標簽中會有#shadow-root字樣標識。

圖片

接下來,我們給他們添加上樣式,進行對比:

<button>hello yichuan</button>
<one-button></one-button>
<style>
button{
font-size: 15px;
padding: 12px;
background-color: #e02727;
color: #fff;
line-height: 15px;
cursor: pointer;
border: none;
}
</style>
<script>
// 1、創(chuàng)建自定義組件的類
class OneButton extends HTMLElement{
constructor(){
super()
// 2、創(chuàng)建shadow dom
this.attachShadow({mode: 'open'})
this.shadowRoot.innerHTML = `<button>hello onechuan</button>`
}
}

// 3、進行自定義組件的注冊
customElements.define("one-button", OneButton)
</script>

運行結(jié)果:

圖片

在上面代碼片段中,在全局對button?標簽進行設(shè)置樣式,運行結(jié)果表明并未影響到shadow dom中的樣式。

6.Template

見到template?模板,使用過vue框架的開發(fā)者就再熟悉不過了,template?標簽本身不會在html?中進行立即渲染,而是用于對待使用的代碼進行標記,在需要被使用的時候才會進行渲染。也正是因為template?的特性,使得我們可以將一些可重復(fù)使用的代碼用template?進行組織,通過javascript獲取它的引用,再添加到DOM中。

For Example:

<one-button></one-button>
<template>
<button>hello yichuan</button>
</template>
<script>
const template = document.createElement("template")
template.innerHTML = `<button>hello onechuan</button>`
// 1、實現(xiàn)自定義組件的類
class OneButton extends HTMLElement{
// 2、定義自定義組件的內(nèi)容
constructor(){
super()
// 2-1、創(chuàng)建影子DOM
this.attachShadow({mode: "open"})
// 2-2、設(shè)置影子DOM的內(nèi)容

this.shadowRoot.appendChild(template.content.cloneNode(true))
}
}
// 3、注冊自定義組件
customElements.define("one-button", OneButton)
</script>

圖片

在上面代碼片段中,可以看到在需要使用的時候?qū)⒛0鍍?nèi)容追加到shadow dom中,即模板內(nèi)容不會立即被渲染,而是在被調(diào)用后才會在頁面進行渲染。

注意:

為什么這里使用Node.cloneNode() 方法添加了模板的拷貝到陰影的根結(jié)點上?

這是因為在添加模板內(nèi)容到shadow dom?時,后續(xù)可以添加樣式信息到模板的style標簽上,也會將其封裝到自定義標簽中,倘若直接將模板添加到原生DOM元素中不起作用的。

7.Slots

插槽由其name屬性標識,并且允許您在模板中定義占位符,當在標記中使用該元素時,該占位符可以填充所需的任何 HTML 標記片段。使用過vue框架的開發(fā)者,對這部分內(nèi)容再熟悉不過了。

<one-button>
<button>hello yichuan</button>
</one-button>
<script>
const template = document.createElement("template")
template.innerHTML = `
<div>
<slot><button>hello onechuan</button></slot>
</div>
`
class OneButton extends HTMLElement{
constructor(){
super()
this.attachShadow({mode:"open"})
this.shadowRoot.appendChild(template.content.cloneNode(true))
}
}
customElements.define("one-button",OneButton)
</script>

運行結(jié)果:

圖片

在上面片段中,在使用自定義標簽的時候,如果<one-button>?中沒有插入任何內(nèi)容,展示的將是hello onechuan?,倘若在在使用時插入了自定義內(nèi)容,則展示自定義內(nèi)容hello yichuan。

當然,當自定義組件中有多個地方使用插槽,可以通過給每個插槽命名進行標識,即:命名插槽。

類似于:vue中的mount。

<one-button>
<button>hello yichuan</button>
<span slot="desc">
slot 這個我熟呀
</span>
</one-button>
<script>
const template = document.createElement("template")
template.innerHTML = `
<div>
<slot>
<button>hello onechuan</button>
</slot>
<slot name="desc"></slot>
</div>
`
class OneButton extends HTMLElement{
constructor(){
super()
this.attachShadow({mode:"open"})
this.shadowRoot.appendChild(template.content.cloneNode(true))
}
}
customElements.define("one-button",OneButton)
</script>

運行結(jié)果:

圖片

?connectedCallback

connectedCallback?方法會在自定義組件插入DOM的首次渲染時調(diào)用一次。此時 shadow dom?已經(jīng)掛載到DOM樹上,對此可以通過connectedCallback?方法來訪問shadow dom上的屬性、子元素以及監(jiān)聽事件。倘若組件被移除或被移動,將會再次被調(diào)用。

<one-button></one-button>
<script>
customElements.define("one-button",class extends HTMLElement{
constructor(){
super()
this.attachShadow({mode:"open"})
this.shadowRoot.innerHTML = `
<button>登錄</button>
`
}
connectedCallback(){
console.log("初始化");
this.addEventListener("click",()=>{
console.log("this id a click handler");
})
}
})
</script>

運行結(jié)果:

圖片

在上面代碼片段中,看到在進行渲染初始化后,會進行執(zhí)行一次connectedCallback的內(nèi)容。

?attributeChangedCallback

監(jiān)聽custom element?自身屬性的增刪改,當發(fā)生狀態(tài)改變時調(diào)用此方法,在使用前必須在一個observedAttributes() ?的靜態(tài)方法中定義要觀察的屬性。該方法返回一個屬性名稱的數(shù)組。一旦observedAttributes?返回了屬性值數(shù)組,則attributeChangedCallback方法會在每次該屬性變化時調(diào)用。

這個方法有三個參數(shù):屬性名稱被改變,該屬性的舊值,以及更新的值。當this.setAttribute()觸發(fā)時,屬性會被更新。

disconnectedCallback

當 custom element? 從文檔 DOM? 中刪除時,disconnectedCallback被調(diào)用。

<script>
customElements.define(
"one-button",
class extends HTMLElement {
//...
disconnectedCallback() {
this.removeEventListener("click", ()=>{
console.log("clicked handled");
});
}
}
);

</script>

8.寫在最后

在我們上述實現(xiàn)的自定義組件,可以在整個項目中重復(fù)使用。簡而言之,在構(gòu)建Web Components時,步驟如下:

  • 首先,必須使用customElements.define()注冊自定義元素;
  • 構(gòu)造函數(shù)會調(diào)用,將節(jié)點添加到shadow dom中
  • 然后,進行一次初始化,執(zhí)行connectedCallback方法;
  • 當元素的屬性被更新時,它的attributeChangedCallback()被觸發(fā);
  • 當一個事件從元素中被移除時,disconnectedCallback()方法被調(diào)用以清理事件監(jiān)聽器。
  • shadow dom - 是DOM的一個封裝版本,用于防止CSS泄露。
  • Slots ?- 用于添加和訪問自定義元素組件的子元素,也有一種特殊的方式來訪問使用命名為Slot的子元素。

本文參考和整理了許多文檔資料,學(xué)而知不足,繼續(xù)前行。

9.參考文章

《Web Components Basic to Advanced》

《MDN文檔》

《重磅!哈啰 Quark Design 正式開源,下一代跨技術(shù)棧前端組件庫》

責任編輯:武曉燕 來源: 前端一碼平川
相關(guān)推薦

2020-07-20 06:35:55

BashLinux

2010-11-19 16:22:14

Oracle事務(wù)

2010-07-13 09:36:25

2010-06-23 20:31:54

2009-08-25 16:27:10

Mscomm控件

2022-08-26 13:48:40

EPUBLinux

2020-09-21 09:53:04

FlexCSS開發(fā)

2013-04-16 10:20:21

云存儲服務(wù)云存儲SLA服務(wù)水平協(xié)議

2021-04-28 10:13:58

zookeeperZNode核心原理

2021-01-19 12:00:39

前端監(jiān)控代碼

2010-11-08 13:54:49

Sqlserver運行

2018-06-22 13:05:02

前端JavaScript引擎

2010-09-27 09:31:42

JVM內(nèi)存結(jié)構(gòu)

2010-11-15 11:40:44

Oracle表空間

2022-06-03 10:09:32

威脅檢測軟件

2011-07-18 15:08:34

2018-02-24 13:21:02

2013-04-10 11:16:19

iPad的MouseE

2009-12-22 14:06:03

距離向量路由協(xié)議

2016-10-20 08:46:17

點贊
收藏

51CTO技術(shù)棧公眾號