Web Components:原生组件化开发新趋势(适合零基础初学者)
🚀 开篇:什么是 Web Components?

你有没有想过,能不能用最原生的方式写出可复用的网页组件?不需要依赖 React、Vue 这样的框架,直接用浏览器支持的技术就能实现?
这就是 Web Components 的魅力!
Web Components 是一套由 W3C 制定的标准,允许我们创建自定义 HTML 标签,这些标签可以像
<button>或<input>一样使用,并且可以在任何前端项目中重复使用。
想象一下,你可以写出一个 <my-button> 自定义按钮,然后在任何网页里直接调用它,就像这样:
<my-button label="点击我"></my-button>
是不是很酷?而且这完全符合浏览器标准,不依赖任何第三方库!
🛠️ 环境准备:搭建我们的开发环境

我们要做的很简单,只需要一个基本的 HTML 页面就可以开始!
步骤 1:创建项目文件夹
打开你的电脑任意目录,新建一个名为 web-components-tutorial 的文件夹。
文件结构如下:
web-components-tutorial/
└── index.html
步骤 2:编写基础 HTML 文件
用你喜欢的代码编辑器(比如 VS Code)打开 index.html,输入以下内容:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Web Components 教程</title>
</head>
<body>
<h1>欢迎学习 Web Components!</h1>
<!-- 我们将在这里插入自定义组件 -->
<script type="module" src="main.js"></script>
</body>
</html>
接着,在相同文件夹下新建一个 main.js 文件:
web-components-tutorial/
├── index.html
└── main.js
这个 JavaScript 文件会存放我们将要写的 Web Components 组件代码。
✅ 小提示:确保你使用的是本地服务器运行项目。如果你不会设置本地服务器,可以安装 Live Server 插件并在 VS Code 中启动。
📚 核心概念:Web Components 的三个核心技术
Web Components 实际上是由三个核心技术组成的“三剑客”:
| 技术名称 | 功能说明 |
|---|---|
| Custom Elements | 创建自定义 HTML 元素 |
| Shadow DOM | 让组件样式和外部隔离 |
| HTML Templates | 预先写好组件结构模板 |
下面我们一个个来讲解,让你轻松掌握它们!
💡 1. Custom Elements:自定义 HTML 标签
这是 Web Components 的核心功能之一。它可以让你创建新的 HTML 标签,比如 <my-header>、<color-box> 等等。
示例:创建一个自定义按钮组件
在 main.js 中加入如下代码:
class MyButton extends HTMLElement {
constructor() {
super();
this.textContent = "我是自定义按钮";
this.style.padding = "10px 20px";
this.style.background = "#4CAF50";
this.style.color = "white";
this.style.border = "none";
this.style.cursor = "pointer";
}
}
// 注册元素,注意名字中必须有短横线(kebab-case)
customElements.define('my-button', MyButton);
现在回到 index.html,在 body 中添加:
<my-button></my-button>
刷新页面,你会看到一个绿色的按钮!
✅ 注意:自定义标签名中必须包含一个短横线(如 my-button),否则会报错。
💡 2. Shadow DOM:让样式互不影响
有时候,我们不希望组件内部的 CSS 被外部影响,也不希望组件里的样式影响外面的内容。这个时候就要用到 Shadow DOM。
示例:给按钮加一个独立的样式空间
修改 main.js 中的按钮类:
class MyButton extends HTMLElement {
constructor() {
super();
// 创建 Shadow DOM
const shadow = this.attachShadow({ mode: 'open' });
// 创建一个 span 元素作为按钮文字
const button = document.createElement('span');
button.textContent = "我是 Shadow 按钮";
// 设置样式
const style = document.createElement('style');
style.textContent = `
span {
padding: 10px 20px;
background: #f44336;
color: white;
display: inline-block;
cursor: pointer;
border-radius: 4px;
}
span:hover {
background: #d32f2f;
}
`;
// 把元素插入到 Shadow DOM 中
shadow.appendChild(style);
shadow.appendChild(button);
}
}
customElements.define('my-button', MyButton);
再次打开页面,你会发现样式不再受外界影响,哪怕你在 index.html 中也写了一个 .button 类,也不会干扰这个组件了!
💡 3. HTML Templates:提前写好模板结构
如果你想让组件更复杂一点,比如里面有多个子元素,可以用 <template> 标签来定义模板。
示例:使用模板创建一个问候组件
在 index.html 中添加模板部分:
<template id="greeting-template">
<style>
.greet {
font-size: 1.2em;
color: purple;
margin: 10px 0;
}
</style>
<div class="greet">你好,世界!</div>
</template>
然后在 main.js 中定义组件:
class GreetingElement extends HTMLElement {
constructor() {
super();
const template = document.getElementById('greeting-template');
const shadow = this.attachShadow({ mode: 'open' });
shadow.appendChild(template.content.cloneNode(true));
}
}
customElements.define('hello-world', GreetingElement);
最后在 index.html 中使用组件:
<hello-world></hello-world>
刷新页面,你会看到一个新的紫色问候语组件!
🔨 实战项目:做一个“折叠面板”组件

接下来我们来动手做一个实用的小组件——折叠面板(Accordion),练习 Web Components 的完整开发流程!
✅ 第一步:设计组件结构
目标:可以传入标题和内容,点击标题时展开/收起内容。
我们需要两个属性:
title:面板标题content:面板内容
✅ 第二步:编写组件代码(main.js)
class AccordionPanel extends HTMLElement {
constructor() {
super();
// 获取属性值
const title = this.getAttribute('title') || "默认标题";
const content = this.getAttribute('content') || "默认内容";
const shadow = this.attachShadow({ mode: 'open' });
// 创建模板结构
const wrapper = document.createElement('div');
const header = document.createElement('div');
const body = document.createElement('div');
// 设置样式
const style = document.createElement('style');
style.textContent = `
div {
border: 1px solid #ccc;
padding: 10px;
max-width: 400px;
margin: 10px 0;
}
.header {
cursor: pointer;
font-weight: bold;
background: #eee;
padding: 8px;
user-select: none;
}
.content {
margin-top: 5px;
display: none;
}
.content.open {
display: block;
}
`;
// 设置内容
header.textContent = title;
header.classList.add('header');
body.textContent = content;
body.classList.add('content');
wrapper.appendChild(header);
wrapper.appendChild(body);
// 点击事件切换显示
header.addEventListener('click', () => {
body.classList.toggle('open');
});
// 添加进 Shadow DOM
shadow.appendChild(style);
shadow.appendChild(wrapper);
}
}
customElements.define('accordion-panel', AccordionPanel);
✅ 第三步:使用组件
在 index.html 中加入两行测试代码:
<accordion-panel title="点击我展开" content="这里是隐藏内容哦~"></accordion-panel>
<accordion-panel title="另一个面板" content="Hello, Web Components!"></accordion-panel>
刷新页面,你就完成了一个可复用的折叠面板组件!👏
❓常见问题解答(FAQ)
Q1:为什么我的组件不显示?
- 检查是否正确注册了组件:
customElements.define()。 - 确保组件标签名含有短横线,如
my-component。 - 查看浏览器控制台是否有错误信息。
Q2:如何向组件传递更多参数?
除了用 getAttribute() 获取字符串,你还可以通过属性监听 (attributeChangedCallback) 监听变化,甚至使用属性反射(reflect)。
Q3:Shadow DOM 和普通 DOM 有什么区别?
Shadow DOM 是组件私有的 DOM 子树,它的样式和脚本对外部是隔离的,避免样式冲突。
Q4:Web Components 能否在 Vue/React 中使用?
可以!因为它是原生浏览器标准,所以可以直接在主流框架中使用。
🧭 学习建议:下一步怎么学?
恭喜你完成了第一个 Web Components 项目!接下来可以尝试:
- ✅ 使用
attributeChangedCallback来监听组件属性变化 - 🔁 增加生命周期钩子函数,如
connectedCallback,disconnectedCallback - 🔬 使用 Web Component 库(如 Lit、Stencil)提升开发效率
- 🔄 在实际项目中集成 Web Components,替代部分 UI 模块
- 🌐 参考官方文档:MDN Web Components
🎯 总结

在本教程中,我们从零开始,逐步了解并实践了 Web Components 的三大核心技术,并成功制作了一个可复用的组件。无论你是刚刚接触前端,还是想深入理解组件化的本质,Web Components 都是一个不可忽视的重要方向。
坚持编码,每天进步一点点 🌱
如果这篇文章对你有帮助,欢迎点赞、转发,让更多朋友一起踏上 Web Components 的旅程吧!

评论 0