Web Components 初体验

157 阅读3分钟

背景

最近工作需要开发一个web插件,支持vue项目和react使用,因此想到跨技术栈的组件开发方案 web components,本文即是技术调研的记录。

Web Components 知识体系.png

一、什么是 Web Components?

Web Components 是一组由 W3C 标准定义的原生 Web 技术,用来创建可复用的 UI 组件,无需依赖第三方框架。
它的核心目标是:像使用 <div> 一样使用自定义标签 <my-button>,并且能跨项目、跨框架复用。

主要包含四大核心技术:

  1. Custom Elements —— 自定义标签,如 <user-card>
  2. Shadow DOM —— 隔离样式和结构,避免 CSS 污染。
  3. HTML Templates —— 通过 <template> 标签定义可复用的 DOM 结构。
  4. ES Modules —— 使用 JavaScript 模块化来组织和复用组件。

二、历史发展

  • 2011 年:Google 提出 Web Components 概念(Polymer 项目推动)。
  • 2014 年:W3C 开始标准化,Chrome 首个支持。
  • 2016 年:其他浏览器逐渐跟进,Shadow DOM v1 确立。
  • 2018 年:大多数现代浏览器实现支持,Polymer 转向 LitElement
  • 2020 年后:Web Components 成为 跨框架通用解决方案,被大型企业应用于设计系统、插件、可复用 SDK。

目前 Chrome、Edge、Firefox、Safari 均已原生支持核心能力。

三、为什么需要 Web Components?

在现代前端开发中,我们常用 Vue、React、Angular 来写组件,但存在几个痛点:

  • 框架绑定:Vue 写的组件在 React 中不能直接用。
  • 样式冲突:多个系统集成时,CSS 容易互相污染。
  • 生态割裂:不同团队、不同技术栈,复用成本高。

Web Components 的优势是:

跨框架复用 —— 写一次,用在任何项目里(React、Vue、Svelte、原生 JS)。
样式隔离 —— Shadow DOM 天然避免全局样式污染。
浏览器原生支持 —— 不依赖额外框架。
适合设计系统 & SDK —— 比如企业 UI 组件库、业务插件。

四、如何使用 Web Components?

下面给一个最小示例。

4.1 定义一个自定义组件

// my-button.js
class MyButton extends HTMLElement {
  constructor() {
    super();
    // 创建 Shadow DOM
    const shadow = this.attachShadow({ mode: "open" });
    
    // 添加样式和 DOM
    shadow.innerHTML = `
      <style>
        button {
          background: #4CAF50;
          color: white;
          border: none;
          padding: 8px 16px;
          border-radius: 6px;
          cursor: pointer;
        }
        button:hover {
          background: #45a049;
        }
      </style>
      <button><slot>默认按钮</slot></button>
    `;
  }
}

// 注册自定义元素
customElements.define("my-button", MyButton);

4.2 使用组件

<script type="module" src="./my-button.js"></script>

<my-button>点击我</my-button>
<my-button>确认提交</my-button>

这时你就能在浏览器里看到一个绿色按钮,并且样式完全隔离,不会影响外部的 CSS。


五、在框架中使用

5.1 在 Vue 中使用

<template>
  <div>
    <my-button @click="handleClick">Vue 按钮</my-button>
  </div>
</template>

<script setup>
const handleClick = () => {
  alert("Vue 触发了 Web Component 事件");
};
</script>

5.2 在 React 中使用

import { useEffect, useRef } from "react";
import "./my-button.js";

export default function App() {
  const btnRef = useRef();

  useEffect(() => {
    btnRef.current.addEventListener("click", () => {
      alert("React 触发了 Web Component 事件");
    });
  }, []);

  return <my-button ref={btnRef}>React 按钮</my-button>;
}

六. 现状与应用场景

如今,Web Components 已经在一些实际项目中大规模使用:

  • 设计系统 / 组件库

    • Salesforce Lightning Web Components
    • Ionic Framework
    • Shoelace(开源 UI 组件库)
  • 跨框架插件 / SDK

    • 内嵌式客服系统、支付插件、埋点 SDK
    • 内部跨团队共用的 UI 模块

在企业场景下,Web Components 特别适合 多框架并存的团队,比如一些大厂内部:老项目用 Vue,新项目用 React,大家仍然可以通过 Web Components 共享核心 UI 和逻辑。


总结

  • Web Components 是浏览器原生的组件化标准。
  • 它解决了 跨框架复用样式隔离 的痛点。
  • 现代浏览器已全面支持,可以安全落地。
  • 适用场景:设计系统、SDK、业务插件、多框架团队协作

一句话总结:
👉 如果你想写一个能在 Vue、React、Angular、甚至原生 JS 中都能用的组件,Web Components 是最佳选择。

参考资料