Web Components:原生组件化开发新趋势
一、开篇:Web Components 是什么?为什么要学它?

你有没有想过,能不能像“拼积木”一样来开发网页呢?比如我们想做一个按钮、一个表单或者一个导航栏,它们可以被多次使用,不需要每次都重新写一遍代码。这就是组件化开发的魅力!
Web Components(网页组件) 就是浏览器给我们提供的一套“原生”的组件化开发工具,它不用依赖任何框架(比如 React 或 Vue),而是直接通过浏览器的支持来实现组件的封装和复用。
✅ Web Components 的三大特点:
- 可复用性:一个组件可以在多个项目中重复使用。
- 封装性:组件内部逻辑对外部隐藏,只暴露需要的接口。
- 原生支持:无需第三方库或框架即可使用,兼容现代浏览器。
🎯 学习 Web Components 的意义
- 不依赖任何框架,适合轻量项目或想深入理解前端本质的同学;
- 组件思想通用性强,为学习 Vue、React 等框架打基础;
- 支持跨项目共享 UI 组件,提高开发效率。
二、环境准备:从零开始搭建开发环境

别担心,Web Components 开发几乎不需要复杂的配置!只要准备好以下基础工具,就能立即上手。
💻 所需工具清单:
| 工具名称 | 用途说明 |
|---|---|
| 浏览器(Chrome/Firefox) | 调试页面,查看效果 |
| 任意文本编辑器(VS Code 推荐) | 编写 HTML、CSS、JS 文件 |
| 本地服务器(如 Live Server 插件) | 模拟在线加载资源的效果 |
🔧 安装 VS Code + Live Server 插件(推荐)
- 下载安装 Visual Studio Code
- 打开 VS Code,点击左侧扩展图标(Extensions)
- 搜索
Live Server,找到后点击 “Install” - 安装完成后,在任意 HTML 文件中右键 → 选择 “Open with Live Server”
📁 项目目录结构(示例):
my-web-components/
├── index.html
└── components/
└── my-button.js
这个结构非常简单清晰,接下来我们将基于这个结构一步步创建我们的第一个组件。
三、核心概念:揭开 Web Components 的神秘面纱
Web Components 技术主要由三个核心技术组成:
1. Custom Elements(自定义元素)
这是我们最常用的一个技术——你可以创建自己的 HTML 标签,比如 <my-button> 或者 <navigation-bar>,这些标签就是你自己定义的组件!
示例:定义一个简单的按钮组件
// components/my-button.js
class MyButton extends HTMLElement {
constructor() {
super();
this.innerHTML = '<button>我是自定义按钮</button>';
}
}
customElements.define('my-button', MyButton);
然后在 HTML 页面中使用它:
<!-- index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>我的第一个 Web Component</title>
<script type="module" src="components/my-button.js"></script>
</head>
<body>
<my-button></my-button>
</body>
</html>

✨ 只要浏览器加载了这段 JavaScript,并注册了 <my-button>,你就可以像普通标签一样使用它了。
2. Shadow DOM(影子 DOM)
Shadow DOM 允许你把一些 HTML 和 CSS 与页面其余部分隔离开,避免样式冲突。它是 Web Components 的“保护罩”。
示例:给按钮加阴影 DOM
// components/my-button.js
class MyButton extends HTMLElement {
constructor() {
super();
// 创建 shadow root
const shadow = this.attachShadow({ mode: 'open' });
// 创建 button 元素
const button = document.createElement('button');
button.textContent = '点我啊';
// 设置样式
const style = document.createElement('style');
style.textContent = `
button {
background-color: lightblue;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
}
`;
// 插入到 shadow DOM 中
shadow.appendChild(style);
shadow.appendChild(button);
}
}
customElements.define('my-button', MyButton);
现在,无论页面上是否有类似 .btn 或其他 button 样式,都不会影响你的组件了。
3. HTML Templates(模板元素)
如果你的组件内容比较复杂,我们可以提前在 HTML 中写好模板,再用 JavaScript 动态加载。
<!-- index.html -->
<template id="my-card-template">
<div class="card">
<h3>卡片标题</h3>
<p>这是卡片的内容区域。</p>
</div>
</template>
// components/my-card.js
class MyCard extends HTMLElement {
constructor() {
super();
const template = document.getElementById('my-card-template').content;
const shadow = this.attachShadow({ mode: 'open' });
shadow.appendChild(template.cloneNode(true));
}
}
customElements.define('my-card', MyCard);
这样你就可以把复杂的 HTML 内容先定义好,再通过组件调用它。
四、实战项目:做一个“天气小插件”组件
现在我们来动手做一个实用的小组件:显示当前城市的天气信息。我们会结合前面介绍的三种核心技术。
🧩 功能目标:
- 创建一个
<weather-widget>自定义组件 - 使用 Shadow DOM 隐藏内部结构
- 从网络获取城市天气数据并展示
步骤一:HTML 结构和脚本引入
<!-- index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>天气小插件</title>
<script type="module" src="components/weather-widget.js"></script>
</head>
<body>
<!-- 使用组件 -->
<weather-widget city="北京"></weather-widget>
</body>
</html>
步骤二:编写 weather-widget.js
// components/weather-widget.js
class WeatherWidget extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
// 获取用户输入的城市名
const city = this.getAttribute('city') || '默认城市';
// 创建基本结构
const container = document.createElement('div');
container.style.fontFamily = 'Arial';
container.innerHTML = `<h2>天气信息</h2><div id="info">正在加载...</div>`;
// 插入到 shadow dom
shadow.appendChild(container);
// 获取真实天气数据(此处模拟 API 调用)
setTimeout(() => {
const fakeData = {
北京: "晴,25℃",
上海: "阴,28℃",
广州: "多云,32℃"
};
const info = shadow.getElementById('info');
info.textContent = `${city}:${fakeData[city] || '暂无数据'}`;
}, 1000);
}
}
customElements.define('weather-widget', WeatherWidget);
🔍 效果预览:
在浏览器中打开页面,你会看到如下效果:
天气信息
北京:晴,25℃
如果你修改标签中的城市名,如:
<weather-widget city="广州"></weather-widget>
结果就会变成:
广州:多云,32℃
✅ 这样我们就完成了一个功能完整的组件!
五、常见问题解答(FAQ)
❓ Q1:为什么写了组件但页面不显示?
- ✅ 检查是否调用了
customElements.define()注册了组件 - ✅ 确保 script 标签类型为
type="module" - ✅ 使用浏览器开发者工具检查控制台是否有错误信息
❓ Q2:Shadow DOM 外的样式会影响组件吗?
- ✅ 一般不会,因为 Shadow DOM 是隔离的
- ⚠️ 如果使用全局类名或字体等资源,仍可能有影响
❓ Q3:如何调试 Web Components?
- ✅ 在 Chrome DevTools 中打开 Elements 面板
- ✅ 找到你写的自定义标签,展开 shadow root 即可查看内部结构
六、学习建议:下一步该往哪里走?
恭喜你完成了第一个 Web Components 项目!这只是一个起点。下面是一些推荐的学习方向:
🔹 持续进阶:
- 学习使用 Slot 插槽(允许父级向组件内传递 HTML 内容)
- 学习属性传值和响应变化(attributeChangedCallback)
- 结合 ES Modules 构建更复杂的组件系统
📚 学习资料推荐:
- MDN 官方文档:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
- Web Components Playground(在线练习工具):https://webcomponents.dev
- 前端大师课程:推荐关注 YouTube 的《JavaScript Mastery》频道
🏁 总结
本文带你从零入门 Web Components,了解了它的核心原理和实际应用,还亲手做了一个天气小插件。你会发现,原生组件开发其实并不难,反而很自由灵活!
只要你掌握了组件化思想,未来无论是继续深入 Web Components,还是转向 Vue、React,都会更容易上手。
💡 记住一句话:组件不是魔法,是你组织代码的新方式。从现在开始,尝试把你常用的 UI 功能都做成组件吧!
如果你喜欢这篇教程,欢迎分享给身边的朋友或留言告诉我你想看下一个什么主题 😊

评论 0