为什么要用 Web Components
React、Vue 的组件好用,但它们绑定各自框架,跨项目、跨框架复用成本高。Web Components 是浏览器原生提供的组件模型:用标准 API 定义自定义元素,写一次、在任何页面(甚至不同框架)里都能像原生标签一样用。它不是要取代框架,而是做"与框架无关"的通用组件。
- Custom Elements用 class 定义自定义标签。
- Shadow DOMDOM 与样式天然隔离。
- slot向组件内部分发内容。
- 跨框架原生标签处处可用。
Custom Elements 自定义元素
用一个继承 HTMLElement 的 class 描述组件,再通过 customElements.define 注册一个带连字符的标签名(必须带连字符,避免和原生标签冲突)。之后就能像 <my-card> 这样在 HTML 里直接用。
class MyCard extends HTMLElement {
connectedCallback() {
this.innerHTML = '<div class="card">' + this.textContent + '</div>';
}
}
customElements.define('my-card', MyCard);
Shadow DOM 样式与结构隔离
直接写 innerHTML 会让组件结构暴露在外部 DOM、样式也容易被页面样式污染。把组件挂到Shadow DOM上,它就成了一个独立的影子树:外部 CSS 穿不进去、内部 CSS 也漏不出来,真正做到组件级样式隔离。
插槽 slot:内容分发
组件不能写死所有内容,要让使用者往里填。在 Shadow DOM 里放 <slot>,使用者写在标签间的内容就会被投射到对应位置。具名 slot 还能分多个槽位,做有标题区、内容区的布局。
属性、观测与生命周期
组件通过 attributes 接收外部参数。想监听属性变化,用 observedAttributes 声明、attributeChangedCallback 响应。常用生命周期:connectedCallback(挂载)、disconnectedCallback(移除)、attributeChangedCallback(属性变)。
static get observedAttributes() { return ['title']; }
attributeChangedCallback(name, oldV, newV) {
if (name === 'title') this.render();
}
跨框架复用与注意事项
因为是原生标签,Web Components 可以嵌进 React、Vue、Angular 任意项目。注意点:体积小、样式要自己管、和框架的双向数据流不互通,复杂交互仍建议用框架,Web Components 更适合做通用 UI 原子组件(按钮、弹窗、卡片)。
落地清单
- 组件标签名必须带连字符。
- 用 Shadow DOM 做样式与结构隔离。
- 用 slot 做内容分发,别写死内容。
- 属性变化用 observedAttributes 监听。
- 通用原子组件优先做成 Web Components。