Web Components:原生组件化开发新趋势
开篇:Web Components 是什么?有什么用?

你有没有想过,能不能像搭积木一样来写网页?比如我做好一个按钮、一个菜单、一个输入框,然后在多个页面甚至多个项目里都能直接“搬”过去用,而不用每次都重新写一遍?听起来是不是很棒?
Web Components 就是实现这种“组件化开发”的一种技术。
它是浏览器原生支持的一套技术标准,不需要依赖 React、Vue 这样的框架,就可以让你创建可复用的、封装良好的自定义 HTML 标签。
比如你可以自己定义一个 <my-button> 标签,里面是带样式的按钮,还可以响应点击事件,然后在哪都可以使用它:
<my-button>点我试试</my-button>
是不是很酷?这就是 Web Components 的魅力所在!
环境准备:搭建一个适合 Web Components 学习的环境

我们来从最基础的开始,不需要安装复杂的工具就能入门,但我们会逐步引导你进入更真实的开发流程。
1. 基础环境:只需要浏览器和文本编辑器
- ✅ 浏览器: 推荐使用 Chrome 或 Edge(Firefox 也可以)
- ✅ 文本编辑器: VS Code 最为常用,免费且强大(下载地址:https://code.visualstudio.com/)
2. 创建你的第一个项目目录结构
新建一个文件夹,比如叫 web-components-demo,在该文件夹中创建以下三个文件:
web-components-demo/
│
├── index.html <-- 主页
├── main.js <-- JS 脚本
└── style.css <-- 样式表(可选)
3. 编写简单的 HTML 测试页面
打开 index.html 文件,写下如下代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Web Components 初体验</title>
<script type="module" src="main.js"></script>
</head>
<body>
<h1>欢迎来到 Web Components 小课堂!</h1>
</body>
</html>
💡 注意这里引入 JS 的方式用了 type="module",这是 ES6 模块的标准写法,也是现代浏览器支持 Web Components 的前提之一。
接下来我们在 main.js 中开始编写组件。
核心概念:Web Components 包含哪几个部分?
Web Components 其实不是一项单一的技术,它是由三项核心技术构成的一个组合拳:
- Custom Elements(自定义元素)
- Shadow DOM(影子 DOM)
- HTML Templates(HTML 模板)
下面我们逐一介绍这些概念,并配上简单的示例。
一、Custom Elements:创建你自己的 HTML 标签
这是 Web Components 的核心功能之一——我们可以注册一个全新的 HTML 元素,比如 <hello-world>。
实践步骤:
- 在
main.js中加入如下代码:
class HelloWorld extends HTMLElement {
constructor() {
super(); // 必须调用一次 super()
// 创建要插入的内容
const text = document.createTextNode("你好呀,Web Components!");
// 把内容添加到这个元素内部
this.appendChild(text);
}
}
// 注册一个新的标签名 'hello-world'
customElements.define('hello-world', HelloWorld);
- 打开
index.html,在 body 中加入:
<hello-world></hello-world>
- 双击打开
index.html文件或用浏览器打开:
你应该能看到显示一句话:“你好呀,Web Components!”
🎉 成功了!你刚刚创建了自己的第一个 Web Component!
二、Shadow DOM:给组件加上封装能力
上面的例子虽然能工作,但如果我们想加样式、结构,不让它影响整个页面怎么办?
这就需要用 Shadow DOM(影子 DOM),可以理解为在组件内部建一个“封闭的小房间”,里面的 HTML 和 CSS 都不会被外部干扰。
实践步骤:
修改 main.js:
class MyComponent extends HTMLElement {
constructor() {
super();
// 创建 shadow root
const shadow = this.attachShadow({ mode: 'open' });
// 创建元素
const div = document.createElement('div');
div.textContent = '我是来自组件的内容';
// 添加样式
const style = document.createElement('style');
style.textContent = `
div {
color: blue;
font-size: 20px;
padding: 10px;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
`;
// 插入内容与样式
shadow.appendChild(style);
shadow.appendChild(div);
}
}
customElements.define('my-component', MyComponent);
再修改 index.html:
<my-component></my-component>
刷新页面你会看到蓝色文字和背景框。而且即使外面有其他 CSS,也改变不了它的样式。
🧠 小贴士: Shadow DOM 有三种模式:
open:JS 可以通过element.shadowRoot访问closed:JS 不能访问- 默认不传参数时就是 open
三、HTML Templates:模板 + 内容分离设计
现在我们要让组件更复杂一些,HTML 结构可能变得很大,这时我们可以通过 <template> 标签把组件的结构提前准备好。
实践步骤:
修改 index.html,添加一个模板:
<template id="card-template">
<style>
.card {
border: 1px solid #ddd;
padding: 10px;
width: 200px;
margin-top: 10px;
background-color: #fff;
}
h2 {
color: green;
}
</style>
<div class="card">
<h2>卡片标题</h2>
<p>这是一个基于 template 构建的卡片组件。</p>
</div>
</template>
修改 main.js,创建模板化的组件:
class CardComponent extends HTMLElement {
constructor() {
super();
const template = document.getElementById('card-template');
const shadow = this.attachShadow({ mode: 'open' });
// 把模板内容复制一份并插入到组件中
const clone = document.importNode(template.content, true);
shadow.appendChild(clone);
}
}
customElements.define('card-component', CardComponent);
最后,在 index.html 里加上:
<card-component></card-component>
刷新页面后,你会发现页面上多了一个漂亮的卡片,而且结构清晰又容易维护。
🎯 总结一下:
Custom Elements给我们提供创建新标签的能力Shadow DOM做到了样式隔离和逻辑封装HTML Template提前保存好结构,便于复用
实战项目:做一个“天气卡片组件”Web Component
为了巩固前面所学,我们来实战做一个简单的 Web Components 项目 —— 天气信息展示组件。
我们将构建一个 <weather-card>,能根据传递的天气数据,显示城市名称、温度和天气状态图标。
第一步:HTML 准备一个容器
在 index.html 中,先留出使用组件的位置:
<weather-card city="北京" temp="25" condition="晴"></weather-card>
第二步:编写 WeatherCard 类
在 main.js 中添加以下代码:
class WeatherCard extends HTMLElement {
constructor() {
super();
// 获取属性值
this.city = this.getAttribute('city') || '未知城市';
this.temp = this.getAttribute('temp') || 0;
this.condition = this.getAttribute('condition') || '阴天';
const template = document.getElementById('weather-template');
const shadow = this.attachShadow({ mode: 'open' });
const clone = document.importNode(template.content, true);
// 替换模板中的动态值
const cityName = clone.querySelector('.city-name');
const temperature = clone.querySelector('.temperature');
const weatherCondition = clone.querySelector('.condition');
cityName.textContent = this.city;
temperature.textContent = `${this.temp} ℃`;
weatherCondition.textContent = this.condition;
shadow.appendChild(clone);
}
}
customElements.define('weather-card', WeatherCard);
第三步:添加模板内容到 HTML
继续在 index.html 中补充模板定义:
<template id="weather-template">
<style>
.weather-card {
border: 1px solid #eee;
width: 220px;
padding: 15px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
background-color: #fafafa;
font-family: Arial, sans-serif;
}
.temperature {
font-size: 24px;
color: #f39c12;
}
.city-name {
font-weight: bold;
font-size: 18px;
margin-bottom: 5px;
}
</style>
<div class="weather-card">
<div class="city-name">城市</div>
<div class="temperature">-- ℃</div>
<div class="condition">天气</div>
</div>
</template>
第四步:测试组件
再次刷新 index.html,应该可以看到这样的展示:
北京
25 ℃
晴
一个完整、可复用、样式独立的天气组件就完成了!
👏 恭喜!你已经掌握了 Web Components 的基本开发套路。
常见问题:初学者常问的问题及解答
下面列出几个新手朋友经常遇到的问题,我们一一来解答:
❓1. 自定义元素的名字必须带短横线吗?
✅ 是的。
因为 HTML 原生元素没有短横线,例如 <button>、<div>。为了让浏览器识别这是用户自定义的标签,规定自定义标签必须包含至少一个连字符(hyphen),如 <my-button>、<user-profile>。
⚠️ 错误示范:<greet> ❌
✔️ 正确命名:<greet-user> ✅
❓2. 我可以用 jQuery 来操作 Web Components 吗?
当然可以!不过需要注意的是:
- 如果你用的是
Shadow DOM,外部 JS 是不能直接操作内部节点的 - 你可以通过暴露 API 的方式来实现交互
例如可以在组件类里定义方法:
class MyComponent extends HTMLElement {
showData() {
console.log("组件的数据已加载");
}
}
然后你在其它地方这样调用:
document.querySelector('my-component').showData();
❓3. 如何在组件内监听点击等事件?
非常简单,只需在 constructor 或生命周期钩子中绑定事件监听器即可。
示例:
class ClickableButton extends HTMLElement {
constructor() {
super();
this.innerText = "点我!";
this.addEventListener('click', this.handleClick);
}
handleClick() {
alert("按钮被点击啦!");
}
}
customElements.define('clickable-button', ClickableButton);
❓4. Web Components 支持哪些浏览器?
主流现代浏览器均支持:
- Chrome ✅
- Firefox ✅
- Safari (部分) ⚠️(建议开启“实验性功能”)
- Edge ✅
对于老旧浏览器如 IE11,需要引入 polyfill
学习建议:下一步学习路线图
你现在已经是 Web Components 的入门玩家了,接下来如果想深入掌握这项技术,可以继续沿着以下几个方向学习:
📚 学习资源推荐
| 类型 | 名称 | 链接 |
|---|---|---|
| 官方文档 | MDN Web Components 指南 | https://developer.mozilla.org/zh-CN/docs/Web/API/Web_components |
| 视频教程 | Web Components 入门讲解 | YouTube 上搜 "Web Components tutorial" |
| 开源组件库 | Open UI | https://open-ui.org/ |

🚀 下一步提升方向
- 🔧 使用 Web Component 构建 UI 组件库(比如按钮、菜单等)
- 🛠 结合构建工具(Vite / Parcel)打包你的组件
- 💡 学习 Lit(LitElement、LitHtml)——基于 Web Components 的现代轻量框架
- 💻 构建跨前端框架的组件系统(React/Vue/Angular 都能使用的组件)
- 🧪 单元测试:为组件添加自动化测试(推荐使用 Jest)
📝 总结一句话:
学会了 Web Components,你就能写出真正意义上的“通用组件”——哪里都能用,不依赖任何框架。
是不是很吸引人?那就快去动手实践吧!
结束语:组件化是未来的方向
从前端开发的演进历程来看,组件化已经成为主流趋势。而 Web Components 是浏览器层面原生支持的方式,具有极强的生命力和未来前景。
无论你是刚入门前端的新手,还是已有 Vue、React 使用经验的开发者,了解并掌握 Web Components 都会是你职业生涯的重要加分项。
祝你早日成为真正的“组件大师”!

评论 0