如果有使用過react或是Vue框架建構component的使用者都知道,不論是為了綁上或解綁事件,或是為了最大限度的加快render 整個Virtual DOM,life cycle(生命周期)一直都是框架中重要的一環。web component也有生命周期,但相比框架使用的life cycle,web component會使用到的方法比較少。
一個完整的custom element,通常是使用Class語法來extends HTMLElement,並且實做四個方法和一個靜態唯讀方法。
class MyWebComponent extends HTMLElement {
constructor() { // class語法固定使用
super();
}
connectedCallback() {
// component 放入DOM時呼叫本方法
}
disconnectedCallback() {
// component 脫離DOM時呼叫本方法
}
static get observedAttributes() {
// 和下面的的方法組合,用來指定監聽屬性的名稱
return [];
}
attributeChangedCallback(name, oldValue, newValue) {
// 和上面的的方法組合,當監聽的屬性有變動時,呼叫本方法
}
adoptedCallback() {
// 限定在使用document.adoptNode時呼叫本方法,平時不會使用
}
}
如果各位對Vue框架熟的話,會發現和Vue的生命周期很像。這是因為Vue在設計就有參考web component。下面說明時我也會多少用一點Vue的語法來說明。
Vue和web component的底層上不是使用同樣的方法實做,所以有些細節還是不相同的。
以Vue來當例子的話,大約就像是mounted吧
本方法通常都是用來做以下的事情
connectedCallback() {
const childrenNodes = this.children;
for (const node of childrenNodes) {
node.addEventListener('click', () => {
console.log('click')
})
}
const Div = document.createElement('div');
Div.innerHTML = 'Hallo World!';
this.appendChild(Div);
}
以Vue來當例子的話,大約就像是beforeDestroy(V2)或beforeUnmount(V3)。
本方法通常都是用來做以下的事情
disconnectedCallback() {
const childrenNodes = this.children;
for (const node of childrenNodes) {
node.removeEventListener('click', () => {
console.log('click')
})
}
}
以Vue來當例子的話,大約就像是watch。
observedAttributes 和 attributeChangedCallback一定要同時使用
observedAttributes只有一個功能,用來回傳要監聽的屬性的陣列。當對應的屬性改變時,就會使用attributeChangedCallback這個方法
static get observedAttributes() {
// 表示只監聽'data-a'和'data-b'這二個屬性的變化
return ['data-a', 'data-b'];
}
attributeChangedCallback(name, oldValue, newValue) {
// 因為'所有屬性'的變化都會使用本方法,需要使用name來分清楚是那個屬性在變化
if (name === 'data-a') {
console.log('data-a', oldValue, newValue)
} else if (name === 'data-b') {
console.log('data-b', oldValue, newValue)
}
}
本方法不會有任何框架的生命周期能對應,平時也幾乎不會使用到,我這裡也不會多做介紹。
如果各位真的想了解,完整的說明連結
https://bignerdranch.com/blog/learn-the-lifecycle-of-a-web-component-by-building-a-custom-element/