Web?Components入門教程示例詳解
Web Components不兼容IE
2011年提出Web Components,為了解決代碼復(fù)用問題,早于React、Vue;
相對于React、Vue組件,Web Components是原生組件,不限制接入方的技術(shù),可以接入到React、Vue等技術(shù)框架中
困境
- 兼容性不足,需要主流瀏覽器的支持,需要平緩的過渡
- 沒有標(biāo)準(zhǔn)的數(shù)據(jù)綁定機制、在處理自定義元素內(nèi)部數(shù)據(jù)、UI更新、組件間參數(shù)傳遞時不夠便捷和友好,目前來看大多還依賴于操控dom去實現(xiàn)UI更新
Web Components核心技術(shù)
- 自定義元素
- HTML模板
- 影子Dom
自定義元素
使用 window.customElements.define
自定義html標(biāo)簽元素,自定義元素需要我們用JS封裝一個,我們在html內(nèi)使用的自定義元素custom-button
就是該類的實例;
自定義標(biāo)簽的生命周期 constructor -> attributeChangedCallback -> connectedCallback
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <custom-button></custom-button> <script> class CustomButton extends HTMLElement { constructor() { super(); console.log("this", this); const info = document.createElement("span"); info.setAttribute("class", "test_custom"); info.textContent = "自測自定義標(biāo)簽"; var container = document.createElement("div"); container.classList.add("container"); this.append(info, container); } } customElements.define("custom-button", CustomButton); </script> </body> </html>
我們可以看到CustomButton
繼承了HTMLElement
,也就是繼承了HTML元素的特性,最后我們執(zhí)行了this.append(DOM)
,也就是將元素內(nèi)容添加到當(dāng)前自定義標(biāo)簽
內(nèi),this
表示自定義元素實例
HTML模板(template、slot)
<template>
:包含一個html片段,不會在html初始化時渲染。主要作用是:通過JavaScript獲取該代碼片段將其放入自定義標(biāo)簽內(nèi)顯示,主要作用于自定義標(biāo)簽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <template id="test_template"> <div class="container"> <span class="test_custom">自測自定義標(biāo)簽</span> </div> </template> <custom-button></custom-button> <script> class CustomButton extends HTMLElement { constructor() { super(); const dom = document.querySelector("#test_template").content; this.append(dom); } } customElements.define("custom-button", CustomButton); </script> </body> </html>
我們可以發(fā)現(xiàn)這種寫法相對于前一種方式,更加易讀
以及便捷
<slot>插槽
:給模板元素傳值,增強模板元素的靈活性和通用性。 slot在使用過程中具備以下特性
- 必須在影子Dom種使用,否則不具備插槽的效果
- 給 Slots 傳值的元素必須是自定義元素的直接子元素,否則傳值失效
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <template id="test_template"> <div class="container"> <span class="test_custom">自測自定義標(biāo)簽</span> <slot name="userName" slot="userName"></slot> </div> </template> <custom-button> <div class="name_cls" slot="userName">張三</div> </custom-button> <script> class CustomButton extends HTMLElement { constructor() { super(); const dom = document.querySelector("#test_template").content; this.append(dom); } } customElements.define("custom-button", CustomButton); </script> </body> </html>
通過上圖發(fā)現(xiàn)我們插入的<div class="name_cls">張三</div>
并沒有插入到container節(jié)點內(nèi),主要是因為我們的slot沒有用在影子dom種,所以瀏覽器將<div class="name_cls">張三</div>
當(dāng)成其正常的元素進(jìn)行渲染了;
<script> class CustomButton extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: "closed" }); const dom = document.querySelector("#test_template").content; shadow.append(dom); } } customElements.define("custom-button", CustomButton); </script>
當(dāng)我們將slot插入在影子dom,可以發(fā)現(xiàn)slot生效了;
另外需要注意的一個點,當(dāng)使用slot的時候下邊這個用法是錯誤的
// 錯誤示范 <custom-button> <div> //不能有這一層級 <div class="name_cls" slot="userName">張三</div> </div> </custom-button>
shadow root(影子Dom)
瀏覽器提供了一種機制用于隔離一段代碼和另一段代碼,說到這里你肯定想到iframe,但有時候iframe會顯得非常的沉重以及隔離了太多,導(dǎo)致我們使用起來非常的麻煩; 我們可以利用shadow root將CSS和HTML綁定在一起封裝成組件,并且其支持天然的樣式隔離;
Element.attachShadow()
方法給指定的元素掛載一個 Shadow DOM,并且返回對 ShadowRoot 的引用。
<script> class CustomButton extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: "closed" }); const dom = document.querySelector("#test_template").content; shadow.append(dom); } } customElements.define("custom-button", CustomButton); </script>
this.attachShadow({ mode: "closed" })
的closed
表示表示 Shadow DOM
是封閉的,不允許外部訪問。如果mode
的值是open
,則表示內(nèi)部的節(jié)點可以被外部訪問;
添加樣式
- 如果自定義元素需要樣式,我們可以定義全局的樣式,例如
custom-button{ ... }
- 正常情況我們應(yīng)該將樣式和自定義標(biāo)簽封裝在一起
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <div>222</div> <template id="test_template"> <div class="container"> <span class="test_custom">自測自定義標(biāo)簽</span> <slot name="userName"></slot> </div> <style> :host { position: relative; top: 10px; } .test_custom { color: red; } div { border: 1px solid black; } </style> </template> <custom-button> <span slot="userName">張三</span> </custom-button> <script> class CustomButton extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: "closed" }); const dom = document.querySelector("#test_template").content; shadow.append(dom); } } customElements.define("custom-button", CustomButton); </script> </body> </html>
:host
:表示當(dāng)前的自定義元素節(jié)點;
另外可以發(fā)現(xiàn)我們定義的div樣式只作用于了影子dom
內(nèi)部元素,對于外部的div沒有任何影響,證明了影子Dom的樣式隔離特性
;
以上就是Web Components入門教程詳解的詳細(xì)內(nèi)容,更多關(guān)于Web Components入門教程的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
js style.display=block顯示布局錯亂問題的解決方法
下面小編就為大家?guī)硪黄猨s style.display=block顯示布局錯亂問題的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09如何在JavaScript中實現(xiàn)私有屬性的寫類方式(一)
這篇文章主要介紹了如何在JavaScript中實現(xiàn)私有屬性的寫類方式。需要的朋友可以過來參考下,希望對大家有所幫助2013-12-12