Nice to see devs picking up web components.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...
Nice to see devs picking up web components.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...
Web components are not analogous to frameworks because frameworks tightly couple the component interface and lifecycle hooks with the component implementations. Those are properly decoupled in web components and you bring whatever rendering layer you prefer.
class MyComponent extends HTMLElement
{
private width: number | undefined; // must be | undefined or
// you'll get a typescript error
constructor()
{
// useless, unpredictable
}
connectedCallback()
{
this.initAttributes();
// using this.width will still require an undefined check at some point
}
initAttributes()
{
this.width = Number(this.getAttribute('width'));
}
}
If you could reliably load attributes in the constructor instead of being forced to do everything in connectedCallback (or even better, load them automatically with decorators), it would make typescript implementations much cleaner. Just some way to validate attributes before connectedCallback, or work with typescript guarantees would make this much more attractiveThe lifecycle of custom elements reflects the behavior of the HTML parser and DOM APIs. Attributes aren't consistently available in the constructor because the HTML parser is streaming and may yield to the main thread at any time. So the element is constructed first, possibly before attributes are parsed. Attribute also aren't available because when element are constructed imperatively they will never have attributes at first, ie:
// ctor is called, no attributes!
const el = document.createElement('my-element');
// now there will be an attribute:
el.setAttribute('width');
You also shouldn't ever consider attributes to be fixed in a web component, since they may be added and removed at any time, and of course may never be set in the first place. You should implement attributeChangedCallback() and give your element defined behavior for any set of possible attributes.Or you can use a helper library like Lit which does let you declare and consume your attributes via decorators.