Web Components são componentes nativos do navegador. Sem React. Sem Vue. Só web standards.
As 3 APIs
Web Components são compostos por 3 specs:
- Custom Elements - Criar tags HTML customizadas
- Shadow DOM - Encapsulamento de CSS/JS
- HTML Templates - Templates reutilizáveis
Custom Elements
Criar um componente é estender HTMLElement:
class UserCard extends HTMLElement {
connectedCallback() {
const name = this.getAttribute('name');
this.innerHTML = `
<div class="card">
<h2>${name}</h2>
<button>Follow</button>
</div>
`;
}
}
customElements.define('user-card', UserCard);
Uso no HTML:
<user-card name="Felipe Moacir"></user-card>
Shadow DOM: Encapsulamento Real
CSS do Shadow DOM não vaza para fora:
class FancyButton extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
button {
background: linear-gradient(45deg, #667eea, #764ba2);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
}
</style>
<button><slot></slot></button>
`;
}
}
customElements.define('fancy-button', FancyButton);
O CSS acima não afeta outros <button> da página.
Reactive Properties
Web Components podem ter propriedades reativas:
class CounterButton extends HTMLElement {
static get observedAttributes() {
return ['count'];
}
connectedCallback() {
this.render();
this.addEventListener('click', () => {
const current = Number(this.getAttribute('count') || 0);
this.setAttribute('count', String(current + 1));
});
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'count') this.render();
}
render() {
const count = this.getAttribute('count') || 0;
this.innerHTML = `<button>Clicks: ${count}</button>`;
}
}
customElements.define('counter-button', CounterButton);
Lifecycle Hooks
Web Components têm lifecycle similar aos frameworks:
connectedCallback()- Montado no DOMdisconnectedCallback()- Removido do DOMattributeChangedCallback()- Atributo mudouadoptedCallback()- Movido para outro documento
Quando Usar?
✅ Design Systems cross-framework
✅ Widgets embeddable (analytics, chat)
✅ Performance crítica (sem bundle)
❌ Apps complexos (sem routing, state)
❌ Precisa de SSR
Bibliotecas
Se quer DX melhor, use:
- Lit - Templates, reatividade
- Stencil - Compiler, TypeScript
- FAST - Microsoft, performance
// Lit exemplo
import { LitElement, html, css } from 'lit';
class MyButton extends LitElement {
static styles = css`button { color: blue; }`;
render() {
return html`<button><slot></slot></button>`;
}
}
customElements.define('my-button', MyButton);
Conclusão: Web Components são o futuro para componentes universais. Mas frameworks ainda ganham para apps completos.