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

如果你刚开始学习前端开发,可能会听说过一个词叫“组件化”。你可以把它理解为“搭积木”式的编程方式——我们把网页中的各个部分封装成一个个独立的小块(也就是组件),然后像搭积木一样组合起来。
而 Web Components 就是浏览器原生提供的一套组件化技术。它的特别之处在于:它是浏览器直接支持的功能,不需要依赖任何框架(如 React、Vue 等)就可以实现自定义组件。
这意味着:
- 你写的组件可以在任意项目中使用(无论是 React 还是 Vue 项目);
- 没有外部依赖,代码更轻量;
- 一旦掌握,你将真正理解前端组件化的底层原理。
是不是很酷?那我们就开始入门吧!
环境准备:搭建最简单的开发环境

第一步:安装文本编辑器
推荐使用 Visual Studio Code(简称 VS Code)。它免费、功能强大、社区活跃,非常适合初学者。
安装步骤如下:
- 打开上面的链接;
- 根据你的操作系统下载安装包;
- 安装完成后打开它。
第二步:创建一个项目文件夹
在电脑上新建一个空的文件夹,比如叫做 web-components-tutorial。
在这个文件夹中,再创建两个文件:
index.htmlmain.js
内容暂时为空,后面我们会逐步填充。
第三步:用浏览器运行代码
最简单的做法是:
- 在 VS Code 中打开这个文件夹;
- 右键点击
index.html文件,选择“Open with Live Server”;如果没有这个选项,请先在 VS Code 的扩展市场搜索并安装 “Live Server” 插件。
- 浏览器会自动弹出页面,显示你的网页内容。
这样我们就准备好了一个可以写和运行 Web Components 的基础环境啦!
核心概念:用简单语言解释 Web Components 的三个关键技术
Web Components 不是一个单独的技术,而是由三个主要 API 组合而成的:
1. 自定义元素(Custom Elements)
这是 Web Components 的核心。我们可以用它来自定义 HTML 元素,例如 <my-button>,就像 <button> 一样直接使用。
示例代码:
<!-- index.html -->
<my-button>点我</my-button>
// main.js
class MyButton extends HTMLElement {
constructor() {
super();
const button = document.createElement('button');
button.textContent = this.textContent;
// 把按钮添加到当前元素内部
this.appendChild(button);
}
}
// 注册新标签
customElements.define('my-button', MyButton);
这段代码做了什么?
- 我们创建了一个类
MyButton,继承了 HTML 原生元素; - 在构造函数里,我们创建了一个真实的
<button>; - 最后注册了这个自定义标签名
my-button。
刷新浏览器,你会看到一个按钮,文字是从标签里拿的。是不是很神奇?
✅ 新手提示:
问:为什么要用 class 和 extends? 答:这些是 JavaScript 的面向对象语法,我们是在创建一种新的 HTML 元素类型。虽然看起来有点难,但它其实只是固定写法,照着写就行!
2. Shadow DOM(影子文档对象模型)
Shadow DOM 让你的组件拥有“私有的样式和结构”,不受外部影响,也避免被其他代码干扰。
比如:你在组件内部写的样式,不会影响全局页面;别人写的 CSS 也不会乱改你组件里的样子。
示例代码:
// main.js
class MyButton extends HTMLElement {
constructor() {
super();
// 创建 Shadow DOM
const shadow = this.attachShadow({ mode: 'open' });
// 创建按钮元素
const button = document.createElement('button');
button.textContent = this.textContent;
// 添加样式
const style = document.createElement('style');
style.textContent = `
button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border-radius: 5px;
border: none;
cursor: pointer;
}
`;
// 将按钮和样式放入 Shadow DOM 中
shadow.appendChild(style);
shadow.appendChild(button);
}
}
customElements.define('my-button', MyButton);
刷新浏览器后你会发现:
- 按钮有蓝色背景和白色文字;
- 即使你之后加了别的 CSS,这个按钮仍然不变样。
这就是 Shadow DOM 的作用,给你组件“独享”的样式空间!
3. HTML 模板()
有时候我们的组件结构比较复杂,如果每次都用 JS 动态创建元素就太麻烦了。这时候可以用 <template> 标签来预定义 HTML 结构。
示例代码:
<!-- index.html -->
<template id="my-card-template">
<div class="card">
<h2>标题</h2>
<p>这是一张卡片的内容。</p>
</div>
</template>
<my-card></my-card>
// main.js
class MyCard extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const template = document.getElementById('my-card-template');
// 克隆模板内容,并添加进 Shadow DOM
const instance = template.content.cloneNode(true);
shadow.appendChild(instance);
}
}
customElements.define('my-card', MyCard);
刷新后你应该能看到一张卡片!这个方法特别适合以后做复杂的组件,提前设计好 HTML 结构非常方便。
总结一下三大核心:
| 技术名称 | 作用 |
|---|---|
| 自定义元素 | 创造新的 HTML 标签 |
| Shadow DOM | 隔离样式和结构,不互相干扰 |
| HTML Template | 提前准备好组件结构,便于复用 |
学完这三个概念,你就掌握了 Web Components 的全部核心技术!
实战项目:从头开始写一个天气小部件组件
我们来做一个实用的例子 —— 制作一个天气小部件,名字叫 <weather-widget>,它会显示一段模拟的天气数据。
第一步:HTML 搭建结构
<!-- index.html -->
<weather-widget city="北京" temperature="20"></weather-widget>
第二步:写组件逻辑和样式
// main.js
class WeatherWidget extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
// 创建基本结构
const container = document.createElement('div');
container.className = 'widget';
const city = document.createElement('h2');
city.textContent = `城市:${this.getAttribute('city')}`;
const temp = document.createElement('p');
temp.textContent = `温度:${this.getAttribute('temperature')}°C`;
// 添加样式
const style = document.createElement('style');
style.textContent = `
.widget {
background-color: #e9f5ff;
padding: 15px;
border-radius: 8px;
width: 200px;
font-family: sans-serif;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
h2 {
margin: 0;
color: #007bff;
}
`;
// 合并所有内容
shadow.appendChild(style);
shadow.appendChild(container);
container.appendChild(city);
container.appendChild(temp);
}
}
customElements.define('weather-widget', WeatherWidget);
刷新浏览器:
你应该能看到一个蓝色标题的天气小卡片,显示“城市:北京,温度:20°C”。
加强理解练习:
现在试着修改 HTML:
<weather-widget city="上海" temperature="25"></weather-widget>
<weather-widget city="广州" temperature="32"></weather-widget>
看看效果如何?每个多实例都能正常工作,说明你成功实现了可复用的自定义组件!
常见问题解答
1️⃣ Q:为什么控制台报错说 cannot redefine custom element?
A:这是因为你多次执行了 customElements.define()。你需要确保每个自定义标签只注册一次。建议每次改动代码后刷新浏览器即可。
2️⃣ Q:我的样式没生效怎么办?
A:检查是否用了 attachShadow,样式必须放进 Shadow DOM 内部才能起效。不能像以前那样写 <style> 放在外部。
3️⃣ Q:能不能给组件加事件响应?
A:当然可以!你可以在组件内部给按钮绑定 click 等事件,示例:
button.addEventListener('click', () => {
alert('按钮被点击了!');
});
4️⃣ Q:怎么传更多参数进去?
A:可以通过自定义属性传入,例如:
<my-component name="Tom" age="20"></my-component>
在组件中通过 this.getAttribute('name') 获取值。
学习建议:下一步该学什么?
恭喜你完成这篇入门教程!你现在已初步掌握了 Web Components 的核心能力,接下来你可以继续深入学习以下方向:
🧠 1. 深入了解 Shadow DOM
- 如何动态更新 Shadow DOM 中的内容;
- 使用
slots实现组件插槽(类似 Vue 的 slot); - 更高级的样式隔离与穿透技巧。
🔧 2. 使用 Lit(LitElement + html)
Lit 是基于 Web Components 的轻量库,提供了更强大的功能和更好的开发体验。适合想要进一步提升开发效率的同学。
💡 3. 构建可发布的组件库
- 如何组织多个自定义组件;
- 如何打包发布到 npm;
- 如何供团队或他人引用使用。
📚 推荐学习资源:
- MDN Web Docs:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
- Lit 官方文档:https://lit.dev/
- W3C 规范参考文档
结语:坚持就是胜利!
Web Components 是现代前端的一个重要趋势,它帮助我们回归原生,同时又保持高度模块化和可维护性。
作为初学者,你现在学到的每一步都意义重大。记住一句话:写代码不是靠天才,而是靠一次次尝试与改进。
继续保持动手实践的习惯,多查文档,多问问题。相信不久的将来,你也能用 Web Components 做出漂亮、高效的组件!
祝你学习愉快,早日成为真正的前端高手!

评论 0