Web Components 封装实战:实现跨框架复用组件
在 React、Vue、Angular 三分天下的今天,组件化开发早已深入人心。但你是否遇到过这样的场景:公司内部既有 Vue2/3 项目,也有 React 项目,还需要维护一些 jQuery 老系统。为了保持 UI 风格统一,难道要为每个框架都写一套组件库吗?
Web Components 提供了一种标准化的解决方案:它允许你创建可重用的自定义元素,这些元素在任何框架中都能像原生 HTML 标签一样工作。本文将带你从零实现一个 Web Component,并探讨其在微前端与跨框架场景下的应用。
TL;DR
- 核心三剑客:Custom Elements(自定义标签)、Shadow DOM(样式隔离)、HTML Templates(结构复用)。
- 生命周期:
connectedCallback(挂载)、disconnectedCallback(卸载)、attributeChangedCallback(属性变化)。 - 跨框架:在 Vue 中直接用
<my-btn>,在 React 中需处理自定义事件的兼容性。 - 最佳实践:推荐使用 Lit 等轻量库简化开发,而非裸写原生 API。
1. 原生实现:手写一个 UserCard 组件
我们来实现一个 <user-card> 组件,支持 avatar 和 name 属性,且样式不被外部污染。
// 1. 定义 HTML 模板
const template = document.createElement('template');
template.innerHTML = `
<style>
.card {
display: flex;
align-items: center;
padding: 16px;
border: 1px solid #eee;
border-radius: 8px;
}
img {
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 16px;
}
h3 {
margin: 0;
font-size: 18px;
}
</style>
<div class="card">
<img src="" alt="avatar" />
<div>
<h3></h3>
<slot name="desc"></slot>
</div>
</div>
`;
// 2. 创建自定义类
class UserCard extends HTMLElement {
constructor() {
super();
// 开启 Shadow DOM,实现样式隔离
this.attachShadow({ mode: 'open' });
this..(template..());
}
() {
[, ];
}
() {
(name === ) {
..(). = newValue;
} (name === ) {
..(). = newValue;
}
}
}
..(, );


