Web Components
custom-elements、shadow-dom。
30 分钟
Web Components
Web Components 是浏览器原生组件模型:Custom Elements 定义标签行为,Shadow DOM 封装样式与 DOM 结构。跨平台场景里,它让 设计系统组件 在 React、Vue、静态页甚至 Electron WebView 中 同标签复用——不绑单一框架。
学习目标
- 编写最小 Custom Element 与 Shadow DOM
- 理解属性、事件、插槽(slot)与框架互操作边界
- 对照路线图 custom-elements、shadow-dom 节点
Custom Element 最小例
class CrmBadge extends HTMLElement {
static get observedAttributes() {
return ["label", "variant"];
}
connectedCallback() {
this.render();
}
attributeChangedCallback() {
this.render();
}
render() {
const label = this.getAttribute("label") ?? "";
const variant = this.getAttribute("variant") ?? "default";
this.innerHTML = `<span class="badge badge--${variant}">${label}</span>`;
}
}
customElements.define("crm-badge", CrmBadge);
HTML 使用:
<crm-badge label="PWA" variant="info"></crm-badge>
生产环境更推荐 Shadow DOM 避免样式泄漏:
const root = this.attachShadow({ mode: "open" });
root.innerHTML = `<style>:host { display: inline-block; } …</style><span>…</span>`;
与 React / html-css 的关系
| 层 | Web Components | React |
|---|---|---|
| 封装 | 标准、框架无关 | 组件 + JSX |
| 样式 | Shadow 边界内隔离 | CSS Modules / Tailwind |
| 状态 | 属性 + 自建逻辑 | props / state / hooks |
React 19 对 Custom Elements 属性/事件映射 有改进,但仍需注意:布尔属性、CustomEvent 名 与 JSX camelCase 的差异。大型 UI 仍常用 react-essentials;Web Components 适合 跨项目共享的小部件(徽章、播放器、警告条)。
html-css-essentials 的语义标签思维延续为 有意义的自定义标签名(含连字符,如 crm-badge)。
构建与工具链
- 原生 ES module 可直接
import './crm-badge.js' - ft-vite 可打包 WC 库;发布时注意 与 tree-shaking