为什么要用 Web Components

React、Vue 的组件好用,但它们绑定各自框架,跨项目、跨框架复用成本高。Web Components 是浏览器原生提供的组件模型:用标准 API 定义自定义元素,写一次、在任何页面(甚至不同框架)里都能像原生标签一样用。它不是要取代框架,而是做"与框架无关"的通用组件。

本文核心知识点
  • Custom Elements用 class 定义自定义标签。
  • Shadow DOMDOM 与样式天然隔离。
  • slot向组件内部分发内容。
  • 跨框架原生标签处处可用。
Web Components 配图:蓝色渐变背景中央方形自定义组件套半透明阴影层,左右各伸出两个插槽口插小方块,扁平科技插画
组件套着阴影层、向两侧伸出插槽,正是 Shadow DOM 加 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();
}