🧩 Web Components = Reusable Elements
Framework components are tied. Web Components are framework-agnostic. Reusable, encapsulated, standards-based.
📝 Web Component Basics
// Custom Element
class MyComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
}
render() {
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
padding: 20px;
background: #f0f0f0;
border-radius: 8px;
}
</style>
<div>
<h2><slot name="title">Default Title</slot></h2>
<p><slot>Default content</slot></p>
</div>
`;
}
}
// Register component
customElements.define('my-component', MyComponent);
// Usage in HTML
<my-component>
<span slot="title">Hello World</span>
<p>This is custom content.</p>
</my-component>
🎯 Advanced Components
// With properties and attributes
class UserCard extends HTMLElement {
static get observedAttributes() {
return ['name', 'email', 'avatar'];
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
this._name = '';
this._email = '';
this._avatar = '';
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'name') this._name = newValue;
if (name === 'email') this._email = newValue;
if (name === 'avatar') this._avatar = newValue;
this.render();
}
render() {
this.shadowRoot.innerHTML = `
<style>
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 16px;
display: flex;
align-items: center;
gap: 16px;
}
img {
width: 64px;
height: 64px;
border-radius: 50%;
}
</style>
<div class="card">
<img src="${this._avatar}" alt="${this._name}">
<div>
<h3>${this._name}</h3>
<p>${this._email}</p>
</div>
</div>
`;
}
}
customElements.define('user-card', UserCard);
💡 Web Component Tips
- Use Shadow DOM for encapsulation
- Define observed attributes
- Use slots for content projection
- Dispatch custom events
- Use with any framework
“Web Components are framework-agnostic. Reusable, encapsulated. Essential for modular web.”
