Web Components 与 Lit 框架实战指南
Sarah Wong | 2026-09-01T08:57:02 | JavaScript, Frontend
讲解 Web Components 标准(Custom Elements、Shadow DOM、Templates)与 Lit 框架的响应式属性、事件系统及跨框架复用能力。
# Web Components 与 Lit 框架实战指南 ## Web Components 三大基石 - **Custom Elements**: 自定义 HTML 标签 - **Shadow DOM**: 样式隔离与封装 - **HTML Templates**: 可复用的 DOM 模板 ## 原生 Web Component ```javascript class UserCard extends HTMLElement { constructor() { super() this.attachShadow({ mode: 'open' }) } static get observedAttributes() { return ['name', 'avatar'] } attributeChangedCallback(attr, oldVal, newVal) { this.render() } connectedCallback() { this.render() } render() { this.shadowRoot.innerHTML = ` :host { display: block; padding: 16px; border-radius: 8px; } .card { display: flex; align-items: center; gap: 12px; } img { width: 48px; height: 48px; border-radius: 50%; } ${this.getAttribute('name') || 'Unknown'} ` } } customElements.define('user-card', UserCard) ``` ## Lit 简化开发 ```typescript import { LitElement, html, css } from 'lit' import { customElement, property, state } from 'lit/decorators.js' @customElement('todo-list') export class TodoList extends LitElement { static styles = css` :host { display: block; font-family: sans-serif; } .item { display: flex; align-items: center; gap: 8px; padding: 8px 0; } .done { text-decoration: line-through; opacity: 0.6; } input[type="text"] { flex: 1; padding: 8px; border: 1px solid #ccc; border-radius: 4px; } ` @property({ type: Array }) items = [] @state() private newItem = '' addItem() { if (!this.newItem.trim()) return this.items = [...this.items, { text: this.newItem, done: false }] this.newItem = '' this.dispatchEvent(new CustomEvent('items-changed', { detail: this.items })) } toggle(index) { this.items = this.items.map((item, i) => i === index ? { ...item, done: !item.done } : item ) } render() { return html` this.newItem = e.target.value} @keyup=${(e) => e.key === 'Enter' && this.addItem()} placeholder="Add todo..." /> ${this.items.map((item, i) => html` this.toggle(i)}> ${item.text} `)} ` } } ``` Lit 组件可以在 React、Vue、Angular 中直接使用,是构建跨框架组件库的理想选择。Shadow DOM 保证样式不会泄漏,也不会被外部样式污染。