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

你有没有想过,在网页上复用一段功能完整的界面组件(比如按钮、输入框、导航栏)有多麻烦?通常我们都要借助像 React 或 Vue 这样的框架来做这件事。
但其实,浏览器本身已经原生支持了一种叫做 Web Components 的方式,让我们可以像使用 <button> 或 <input> 一样,创建和使用自定义的 HTML 元素!
🎯 简单一句话:Web Components 是一种浏览器原生支持的技术,让我们能够自定义 HTML 元素,并像普通 HTML 标签一样使用它们。
这有什么好处呢?
- 📦 模块化开发:可以将功能封装成一个个独立组件
- 🧩 跨项目复用:写一次组件,多个项目都可以用
- ⚡ 无需依赖框架:没有 React/Vue,也能实现“组件化”
接下来我们就从零开始,一步步带你走进这个全新的世界!
环境准备:搭建你的第一个 Web Components 环境

所需工具
要开始学习 Web Components,你只需要一个现代浏览器(推荐 Chrome),以及一个代码编辑器。
🔧 必备工具:
| 工具 | 说明 |
|---|---|
| 浏览器 | 推荐 Chrome 或 Edge(对 Web Components 支持最好) |
| 编辑器 | VS Code(免费,功能强大) |
| HTTP 服务 | 可选,为了方便测试,推荐安装 live-server |
安装步骤
步骤 1:下载并安装 VS Code
👉 地址:https://code.visualstudio.com/
安装完成后打开即可。
步骤 2:安装 Live Server 插件
VS Code 中点击左侧扩展图标 → 搜索 “Live Server” → 安装插件
步骤 3:创建项目文件夹
新建一个文件夹,比如叫 web-components-tutorial
结构如下:
web-components-tutorial/
│
├── index.html
└── main.js
然后右键点击 index.html 文件,选择 “Open with Live Server”,就可以在浏览器中运行了 ✅
核心概念:一文讲透 Web Components 的三个关键技术

Web Components 不是一个单独的技术,而是由三个主要技术组成的“组合拳”。理解这三个核心技术,你就理解了 Web Components 的核心思想。
1. 自定义元素(Custom Elements)
你可以定义自己的 HTML 元素,例如 <my-button>,它本质上是一个 JavaScript 类。
// main.js
class MyButton extends HTMLElement {
constructor() {
super();
this.innerHTML = "我是自定义按钮";
}
}
customElements.define("my-button", MyButton);
HTML 使用方法:
<!-- index.html -->
<my-button></my-button>
💡 小提示:标签名必须包含一个短横线
-,比如my-button,不能是mybutton。
2. Shadow DOM(影子 DOM)
Shadow DOM 让我们可以把组件内部的样式和结构与外部页面隔离,避免冲突。
// main.js
class MyInput extends HTMLElement {
constructor() {
super();
// 创建一个 Shadow Root
const shadow = this.attachShadow({ mode: 'open' });
// 添加内容和样式
const input = document.createElement('input');
input.setAttribute('type', 'text');
input.placeholder = '请输入内容';
const style = document.createElement('style');
style.textContent = `
input {
border: 1px solid #4CAF50;
padding: 8px;
font-size: 16px;
width: 200px;
}
`;
shadow.appendChild(style);
shadow.appendChild(input);
}
}
customElements.define("my-input", MyInput);
HTML 使用方法:
<my-input></my-input>
🎯 效果:即使你整个网站有别的 input 样式,这个组件的样式也不会被影响!
3. 模板标签(HTML Templates)
我们可以使用 <template> 标签来定义组件模板,这样可以更清晰地组织结构。
<!-- index.html -->
<template id="greeting-template">
<style>
.greet {
color: blue;
font-size: 20px;
}
</style>
<div class="greet">你好,Web Components!</div>
</template>
<script src="main.js"></script>
对应的 JS 代码:
// main.js
class GreetingComponent extends HTMLElement {
constructor() {
super();
const template = document.getElementById("greeting-template");
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(template.content.cloneNode(true));
}
}
customElements.define("greeting-component", GreetingComponent);
HTML 使用方法:
<greeting-component></greeting-component>
实战项目:构建一个可复用的 todo-item 组件

我们来实战开发一个待办事项列表中的单项条目组件,体验完整的 Web Components 构建过程。
目标效果
展示一个带有删除按钮的条目,如:
- 学习 Web Components [X]
Step 1:创建 HTML 结构
<!-- index.html -->
<template id="todo-item-template">
<style>
.item {
display: flex;
justify-content: space-between;
align-items: center;
background: #f4f4f4;
padding: 10px;
margin-bottom: 5px;
border-radius: 4px;
}
.delete-btn {
background: red;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
border-radius: 3px;
}
</style>
<div class="item">
<slot name="content"></slot>
<button class="delete-btn">X</button>
</div>
</template>
Step 2:编写 JS 类逻辑
// main.js
class TodoItem extends HTMLElement {
constructor() {
super();
const template = document.getElementById("todo-item-template");
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(template.content.cloneNode(true));
const button = shadowRoot.querySelector('.delete-btn');
button.addEventListener('click', () => {
this.remove(); // 删除自己
});
}
}
customElements.define("todo-item", TodoItem);
Step 3:在页面中使用组件
<!-- index.html -->
<body>
<todo-item><span slot="content">完成教程作业</span></todo-item>
<todo-item><span slot="content">预习明天课程内容</span></todo-item>
</body>
✅ 最终效果:你会看到两个带删除功能的待办项!
常见问题解答(FAQ)
❓ Q1:为什么我的组件不显示?
✔️ 可能原因:
- 没有正确调用
customElements.define - 组件名称没有短横线,比如用了
mybutton而不是my-button - HTML 中没有引入
main.js
✅ 解决办法: 检查控制台是否有报错信息,确保 JS 正确执行。
❓ Q2:组件内 CSS 样式不起作用?
✔️ 原因可能是:
- 样式没放在 Shadow DOM 内部
- 漏掉了
mode: 'open'导致无法访问
✅ 解决办法:
确保样式插入到 shadowRoot,或者使用 <template> 引入。
❓ Q3:如何传递参数给组件?
💡 方法有两种:
通过 Attributes 设置
<my-component title="标题"></my-component>JS 中获取:
const title = this.getAttribute('title');使用
observedAttributes配合监听变化static get observedAttributes() { return ['title']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'title') { console.log('title changed to:', newValue); } }
学习建议:下一步该学什么?
恭喜你完成了第一个 Web Components 组件!接下来你可以继续深入以下方向:
✅ 推荐学习路径
| 学习内容 | 说明 |
|---|---|
| 深入 Shadow DOM | 学习 Shadow DOM 高级特性,如继承、事件冒泡 |
| 使用属性传值 | 掌握 Attribute 和 Properties 的区别 |
| 生命周期回调 | 如 connectedCallback, disconnectedCallback |
| 组件间通信 | 如何让组件之间互相通信或触发事件 |
| 结合现有框架 | 如何在 React/Vue 中使用 Web Components |
| 工程化打包 | 使用 Rollup/Webpack 打包组件库 |

📌 推荐资源:
- MDN 官方文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_components
- Web Component Playground(在线实验环境):https://webcomponents.dev
总结:开启属于你的组件化开发旅程
本教程为你打开了 Web Components 的大门,它是一门真正“原生”的组件化技术,适合希望摆脱框架限制或构建高度可复用组件的开发者。
📌 回顾关键点:
- Web Components 由 Custom Elements + Shadow DOM + Template 组成
- 组件可以像 HTML 标签一样使用
- 不需要依赖任何框架,完全原生
- 学会后可以在任何前端项目中通用
现在就动手实践吧,别忘了多试几个小项目练手,比如做一个菜单组件、一个数据表格组件等。你也可以尝试将 Web Components 应用于实际工作中,提升效率!
祝你学习愉快,成为 Web 组件化开发高手!🚀

评论 0