Web Components:构建与框架无关的用户界面

124 阅读7分钟

Web Components基于Web标准构建,可在任何HTML环境中使用,实现UI元素级别的可重用性和封装性。它们具有框架无关性、高性能和良好的安全性,并已被GitHub、Salesforce和Adobe等公司广泛采用。

译自:How To Build Framework-Agnostic UIs With Web Components

作者:Alexander T. Williams

Web 开发一直是在灵活性和可维护性之间寻求平衡。框架承诺快速提高生产力,但通常会带来一个问题:锁定。一旦你深入使用 React、Vue 或 Angular,想要从中脱身就像在飞行途中重新连接飞机的线路。

Web Components 颠覆了这个等式。它们提供了一种构建独立 UI 元素的方法,不受框架政治和版本更迭的影响。在 2025 年,随着原生浏览器支持比以往任何时候都更好,它们不仅仅是一个有趣的实验,而是主要的事件。

为什么 Web Components 正迎来高光时刻

多年来,Web Components 在技术上相当于一支地下乐队,理论上很酷,但难以被主流采用。现在,浏览器支持已经成熟,很少需要 polyfill,开发人员也看到了长期的回报。

与框架特定的组件不同,Web Components 基于 Web 标准构建:自定义元素、Shadow DOM 和 HTML 模板。这意味着它们可以在任何 HTML 工作的地方工作。

当团队谈论“面向未来”时,这就是他们的意思。一个按钮、模态框或数据网格,如果构建为 Web Component,就可以在框架迁移中幸存下来,可以放入遗留应用程序中,或者可以愉快地生活在一个全新的项目中。

因为它们运行在原生 API 上,所以不依赖于框架的渲染层;只有精简的、浏览器原生的性能。这不仅仅是关于技术弹性,而是关于未来业务的敏捷性,让公司可以自由创新,而无需在技术栈改变时进行代价高昂的重写。

Web Component 的剖析

Web Components 的核心在于三个支柱:自定义元素、Shadow DOM 和 HTML 模板。你可以使用 customElements.define 定义一个自定义 HTML 标签,使用 Shadow DOM 封装其样式和 DOM 结构,并使用可重用的 HTML 模板来构建它。

class FancyButton extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = `
      <style>
        button {
          background: #6200ea;
          color: white;
          border: none;
          padding: 10px 20px;
          border-radius: 5px;
          cursor: pointer;
          font-weight: bold;
          transition: background 0.3s ease;
        }
        button:hover {
          background: #4b00b5;
        }
      </style>
      <button><slot></slot></button>
    `;
  }
}

customElements.define('fancy-button', FancyButton);

这个 <fancy-button> 可以放入任何 HTML 页面中,无论它是由 Angular、静态站点生成器还是纯 HTML 驱动。无需依赖项,无需构建工具,它的美妙之处在于它的可移植性——编写一次,随处使用,无论是用于复杂的 UI 元素还是简单的元素,比如向表单添加二维码。所有这些都无需重写或用框架特定的语法包装。

Shadow DOM:没有隔离焦虑的封装

Shadow DOM 是使 Web Components 可预测的超能力。它创建了一个 DOM 元素和样式的范围子树,这些元素和样式不会泄漏出去或被全局 CSS 覆盖。这使得它们非常适合需要在多个项目中保持一致外观和行为的设计系统。

封装消除了类名冲突和 CSS 特异性之争,同时仍然允许通过 CSS 变量进行受控的自定义:

button {
  background: var(--primary-color, #6200ea);
}

这允许主题化,而不会牺牲内部稳定性。团队可以确信,没有外部样式表会破坏组件,但仍然保留为不同产品进行品牌化和自定义的灵活性。这是大型开发团队迫切需要的控制和适应性之间的平衡

HTML 模板和可重用性

HTML 模板是 Web Components 故事中一个微妙但强大的部分。<template> 元素允许你定义一次标记和样式,克隆它们,并将它们附加到任何实例。

<template id="card-template">
  <style>
    .card {
      border: 1px solid #ccc;
      padding: 10px;
      border-radius: 8px;
      background: white;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
  </style>
  <div class="card">
    <slot name="title"></slot>
    <slot name="content"></slot>
  </div>
</template>

这种方法避免了 JavaScript 中重复的 HTML 字符串,并简化了更新——更改模板会更新组件的每个新实例。在实践中,它可以减少代码重复,并在整个应用程序生态系统中强制执行一致的 UI 结构,从而产生一个设计合理的网站。更不用说,它使开发团队更高效和灵活。

框架世界中的 Web Components

“与框架无关”的标签并不意味着你完全放弃框架;相反,这意味着你的组件超越了它们。事实上,许多团队现在在 React 内部使用 Web Components、Vue 和 Angular 应用程序来统一他们的 UI 层,同时允许每个应用程序使用其首选的框架。

考虑一家公司,其产品套件构建在多个技术栈中。如果没有 Web Components,每个产品团队都必须维护自己的按钮、表单和模态框实现。有了 Web Components,他们都使用相同的库,确保一致的设计并减少重复的工作。

function App() {
  return <fancy-button>Click Me</fancy-button>;
}

在 React 中,就是这么简单——没有生命周期钩子,没有 prop 类型定义,只需像原生标签一样放入即可。

性能考虑

Web Components 利用原生 API 进行渲染,这减少了与管理虚拟 DOM 的框架相比的 JavaScript 开销。不过,效率取决于仔细的实现:避免在构造函数中进行昂贵的操作,尽量减少 DOM 操作并优先使用 CSS 过渡而不是 JavaScript 动画

你可以使用延迟加载进一步优化。组件只能在它们进入视口时注册:

if ('IntersectionObserver' in window) {
  const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        import('./fancy-button.js');
        observer.unobserve(entry.target);
      }
    });
  });

  document.querySelectorAll('fancy-button').forEach(el => observer.observe(el));
}

这减少了初始加载时间,提高了 Core Web Vitals 分数,并提供了更快的首次交互。

安全性和可维护性

安全是 Web Components 经常被忽视的优势。Shadow DOM 隔离减少了基于样式的攻击的机会,并限制了来自外部源的 DOM 操作。通过控制内部 DOM 结构,你可以减少潜在的 XSS 漏洞的攻击面——尽管用户生成的内容仍然需要清理。

从维护的角度来看,Web Components 非常出色,因为它们基于稳定的 Web 标准,而不是供应商的路线图。它们可以通过 npm 分发,独立进行版本控制,并集成到任何构建过程中。企业受益于在框架升级期间减少的返工,这使它们成为长期项目的理想选择。

Web Components 的实际应用

Web Components 不再是实验性的。GitHub、Salesforce 和 Adobe 等公司在生产中使用它们,依赖于它们的稳定性和适应性。GitHub 的 <details-menu> 是一个很小但很关键的例子,说明了组件如何在不臃肿技术堆栈的情况下增强功能。Salesforce 的 Lightning Web Components 展示了它们在大规模、高性能环境中的潜力。

这些实际的实现证明了 Web Components 可以在扩展的同时保持灵活性。对于面临频繁收购或维护各种技术堆栈的组织,它们可以作为前端开发的统一力量。

结论

框架将不断发展,流行度也会起起落落,但 Web Components 位于这种变化之上。它们是你防止锁定的保险,是你通往真正可重用 UI 的门票,也是你跨越不同技术堆栈的桥梁。

在一个每个项目都有自己怪癖的世界里,一次构建并随处部署的能力不仅仅是方便,而是战略性的。Web 终于赶上了通用组件的承诺,最聪明的团队已经在投入其中。问题不再是是否应该使用它们,而是你能多快开始使用它们。