Web Components是現代Web開發中用于創建可重用和封裝的自定義HTML元素的一組技術。它包括Custom Elements、Shadow DOM、HTML Templates和Slots。
定義自定義元素
定義一個新的HTML元素,這可以通過customElements.define方法完成
class MyElement extends HTMLElement {
constructor() {
super(); // 調用超類的構造函數
this.attachShadow({ mode: 'open' }); // 創建Shadow Root
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
/* 在這里定義Shadow DOM內的樣式 */
</style>
<slot>默認內容</slot>
`;
}
}
customElements.define('my-element', MyElement);
使用Shadow DOM封裝樣式
Shadow DOM
允許我們在組件內部定義私有的CSS樣式,這些樣式只影響組件內部的元素,不會泄漏到外部DOM。在上面的connectedCallback
中,創建了Shadow Root
,并添加了樣式:
this.shadowRoot.innerHTML = `
<style>
div {
color: blue;
font-size: 24px;
}
</style>
<div><slot></slot></div>
`;
<my-element>
內部的任何文本都將使用藍色字體和24px的大小。
插入內容
使用<slot>
元素,我們可以允許用戶向自定義元素內插入內容,這些內容會被插入到Shadow DOM中相應的位置:
<my-element>
<span>這是插入的內容</span>
</my-element>
在上面的MyElement類中,<slot>元素會顯示用戶插入的內容。
交互和事件
自定義元素可以有自己的一套事件和交互邏輯。例如,可以添加事件監聽器:
class MyElement extends HTMLElement {
// ...
disconnectedCallback() {
// 清理資源或執行斷開連接時的操作
}
// 添加事件監聽器
buttonClickHandler() {
console.log('Button clicked!');
}
connectedCallback() {
// ...
this.shadowRoot.querySelector('button').addEventListener('click', this.buttonClickHandler.bind(this));
}
}
復用和組合
自定義元素可以嵌套在其他自定義元素中,或者在多個地方重復使用,從而實現組件的復用。
<div>
<my-element>
<button>點擊我</button>
</my-element>
<my-element>
<button>再次點擊我</button>
</my-element>
</div>
兩個<my-element>
都可以響應點擊事件,并且它們的樣式和邏輯都是封裝在各自的Shadow DOM內,互不干擾。
屬性和屬性觀察
為了使自定義元素更加靈活和可配置,我們可以為其定義屬性,并觀察這些屬性的變化以響應式地更新組件內部的狀態或UI。
定義屬性
在自定義元素類中,可以通過observedAttributes靜態屬性來聲明需要觀察的屬性列表:
static get observedAttributes() {
return ['my-attribute'];
}
屬性變化的響應
然后,通過覆蓋attributeChangedCallback方法來響應屬性變化:
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'my-attribute') {
console.log(`my-attribute changed from ${oldValue} to ${newValue}`);
// 根據屬性變化更新UI或邏輯
}
}
使用屬性
在HTML中,可以通過自定義元素標簽設置這些屬性:
<my-element my-attribute="someValue"></my-element>
樣式隔離與穿透
Shadow DOM提供了樣式隔離,但有時我們可能希望某些全局樣式也能影響到Shadow DOM內部。可以使用CSS的:host偽類來控制自定義元素本身的樣式,而:host-context(selector)則允許根據宿主上下文來改變樣式。
如果需要從外部影響Shadow DOM內部的樣式,可以利用CSS變量(Custom Properties):
/* 在全局樣式或父組件中定義變量 */
:root {
--my-color: blue;
}
/* 在Shadow DOM中使用這些變量 */
<style>
div {
color: var(--my-color);
}
</style>
生命周期方法
除了connectedCallback
, disconnectedCallback
, 和 attributeChangedCallback
,自定義元素還有其他生命周期方法,比如adoptedCallback
,當元素被移動到新的文檔時調用。
性能考量
- 懶加載與按需創建:確保自定義元素只在需要時創建和加載,避免不必要的性能損耗。
- 優化
Shadow DOM
:盡量減少Shadow DOM
的深度和復雜度,避免過度使用復雜的CSS選擇器,因為它們可能影響到渲染性能。
跨框架兼容性
Web Components
設計為原生Web標準,這意味著它們可以在任何支持Web Components
的瀏覽器中工作,不論使用的是Angular
、React
還是Vue
等前端框架,都能無縫集成。