Web Components:原生组件化开发新趋势(面向零基础初学者的教程)
开篇:什么是 Web Components?它用来做什么?

在开始学习之前,我们先来聊聊Web Components 是什么?
简单来说,Web Components 是浏览器原生提供的一种构建可复用、独立网页组件的技术。你可以把它理解成一个“乐高积木”,每一块积木是一个小功能或界面模块,可以随时拼接到不同的项目里,而无需担心冲突。
过去我们做网页开发时,如果要复用某一块功能(比如一个按钮、一个导航栏),我们需要手动复制代码,或者依赖第三方框架(如 React、Vue)才能实现更方便的组件化开发。
而现在,Web Components 让你不用任何额外工具,仅靠浏览器本身就可以创建高度模块化的自定义元素。它可以和其他技术兼容,比如你可以把它集成到 Vue 或 React 项目中,也可以单独使用它。
它有哪些优势?
- 原生支持:不需要安装额外框架,现代浏览器都支持。
- 可重用性强:写一次,可以在多个项目中使用。
- 封装性好:样式、逻辑都包裹在组件内部,不会影响外部页面。
- 跨框架兼容:既可以在原生 HTML 中使用,也可以在 React、Vue 等框架中使用。
举个例子:
如果你做一个电商网站,里面有一个产品卡片,每次都要重复写 HTML 和 CSS。现在你就可以用 Web Components 把它封装成 <product-card> 这样的自定义标签,在不同页面上直接调用这个组件,就像用 <button> 标签一样方便!
接下来,我们就从头开始一步步学起吧 🚀
环境准备:搭建你的第一个 Web Components 开发环境

新手同学可能最关心:“我需要安装什么东西吗?”
好消息是:几乎不需要额外安装!只需要一个文本编辑器和现代浏览器即可开始。
所需工具:
- ✅ 文本编辑器:推荐 VS Code
- ✅ 浏览器:Chrome、Edge、Firefox 都行(建议 Chrome)
- ✅ 本地服务器(可选):用于测试加载问题(如 VS Code 插件 Live Server)
小提示:虽然可以直接打开
.html文件运行,但为了更好的体验,推荐使用本地服务器,避免因“文件协议限制”导致的报错。
第一步:新建一个 HTML 文件
让我们先创建一个简单的 HTML 页面作为入口文件。
<!-- index.html -->
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>我的第一个 Web Component</title>
</head>
<body>
<h1>Hello Web Components!</h1>
<!-- 我们将在后面放我们的组件 -->
<script type="module" src="./my-component.js"></script>
</body>
</html>
注意:<script type="module"> 的使用很重要,因为我们要使用 ES6 模块语法来定义组件。
第二步:创建 Web Component 的 JS 文件
创建一个 my-component.js 文件,并写下以下内容:
// my-component.js
class MyComponent extends HTMLElement {
constructor() {
super(); // 必须调用父类构造函数
this.innerHTML = `<p>这是一个简单的 Web Component</p>`;
}
}
// 注册组件,必须以短横线命名
customElements.define('my-component', MyComponent);
这段代码做了三件事:
- 创建了一个叫
MyComponent的类,继承自HTMLElement - 在构造函数中设置了组件的内容
- 通过
customElements.define()方法注册了组件,名字为my-component
第三步:在 HTML 中使用组件
回到 index.html 文件,加入我们刚刚创建的组件标签:
<body>
<h1>Hello Web Components!</h1>
<!-- 使用我们自定义的组件 -->
<my-component></my-component>
<script type="module" src="./my-component.js"></script>
</body>
刷新一下浏览器,你应该能看到页面显示了:“这是一个简单的 Web Component”。
🎉 成功啦!
核心概念讲解:轻松理解关键术语

Web Components 由三个主要部分组成,下面我用生活中的比喻带大家理解它们。
1. Custom Elements(自定义元素)
这是整个 Web Components 的核心部分。
👉 你可以把 Custom Elements 理解成是你自己写的 HTML 标签。比如 <button> 是系统自带的,<product-card> 是你自己写的。
- 必须继承
HTMLElement - 必须用
customElements.define()注册 - 名字必须包含短横线(如
cool-button)
2. Shadow DOM(影子 DOM)
想象一下你在玩手电筒,光打到墙上形成了影子。你只能看到影子,看不到实际的光源位置。
Shadow DOM 就是这样一个“隔离区域”。它让你的组件样式和外部页面隔离开来,不会互相干扰。
举个例子:你想在组件里写一段文字并加红色背景,外面的页面即使也有同名类名,也不会受到影响。
✅ 示例:
class MyStyledComponent extends HTMLElement {
constructor() {
super();
// 创建 Shadow DOM
const shadow = this.attachShadow({ mode: 'open' });
// 创建一个 div 并设置样式
const div = document.createElement('div');
div.textContent = '我是被包裹的内容';
div.style.background = 'lightpink';
div.style.padding = '10px';
// 把 div 放入 Shadow DOM
shadow.appendChild(div);
}
}
customElements.define('my-styled-component', MyStyledComponent);
在 HTML 中使用:
<my-styled-component></my-styled-component>
你会看到粉色背景的 div 出现,并且不会受外层样式干扰 ✨
3. HTML Templates(HTML 模板)
有时候,我们在组件里要用很多复杂的结构,如果每次都手动拼接字符串就很麻烦。
这时我们就可以用 <template> 标签来定义模板,然后通过 JS 加载它。
✅ 示例:
<!-- index.html -->
<template id="greeting-template">
<style>
p { color: green; }
</style>
<p>你好,世界!</p>
</template>
<script type="module" src="./template-component.js"></script>
接着创建 template-component.js:
class GreetingComponent extends HTMLElement {
constructor() {
super();
const template = document.getElementById('greeting-template').content;
const shadow = this.attachShadow({ mode: 'open' });
shadow.appendChild(template.cloneNode(true));
}
}
customElements.define('greeting-component', GreetingComponent);
现在在页面中插入:
<greeting-component></greeting-component>
你会发现绿色的文字出现在自己的组件里,而且完全不受外部样式影响 ❤️
实战项目:用 Web Components 做一个天气预报组件

我们已经掌握了基础知识,现在来动手做个小项目吧 👷♂️
目标:制作一个叫做 <weather-widget> 的组件,输入城市名就能显示天气信息(模拟数据)。
步骤一:添加输入框和按钮
我们先创建组件的基本外观。
创建文件 weather-widget.js:
class WeatherWidget extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
// 模拟 UI
shadow.innerHTML = `
<input type="text" id="city-input" placeholder="输入城市名" />
<button id="btn-fetch">查询天气</button>
<div id="result"></div>
`;
}
}
customElements.define('weather-widget', WeatherWidget);
在 HTML 中添加组件:
<weather-widget></weather-widget>
打开后你能看到输入框和按钮 ✔️
步骤二:添加事件监听与模拟数据展示
我们希望点击按钮后能显示“城市 + 天气”的结果。
修改 weather-widget.js:
class WeatherWidget extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<input type="text" id="city-input" placeholder="输入城市名" />
<button id="btn-fetch">查询天气</button>
<div id="result"></div>
`;
const btn = shadow.getElementById('btn-fetch');
const input = shadow.getElementById('city-input');
const result = shadow.getElementById('result');
btn.addEventListener('click', () => {
const city = input.value;
if (city) {
// 模拟获取天气数据
const weather = Math.floor(Math.random() * 30) + 10 + "℃";
result.textContent = `${city}当前天气:${weather}`;
} else {
result.textContent = '请输入城市名称。';
}
});
}
}
customElements.define('weather-widget', WeatherWidget);
刷新页面,输入城市名,点击按钮会出现随机温度 ❄️
步骤三:美化组件样式
我们可以给组件加上一点点样式,让它看起来更好看。
继续修改 weather-widget.js:
shadow.innerHTML = `
<style>
:host {
display: inline-block;
border: 1px solid #ddd;
padding: 15px;
border-radius: 8px;
font-family: sans-serif;
max-width: 300px;
background-color: #f9f9f9;
}
input, button {
margin: 5px 0;
padding: 6px;
width: 100%;
}
#result {
margin-top: 10px;
color: #333;
}
</style>
<input type="text" id="city-input" placeholder="输入城市名" />
<button id="btn-fetch">查询天气</button>
<div id="result"></div>
`;
这样组件就变得好看多了 😊
常见问题解答(FAQ)
❓Q1:为什么我的 Web Component 不显示?
答:请检查以下几点:
- 是否用了
<script type="module">? - 自定义元素的名字是否包含短横线(例如
hello-world而不是HelloWorld)? - 是否遗漏了
customElements.define()? - 如果用的是
file://协议,请改为使用本地服务器运行。
❓Q2:能不能给组件传参数?
答:当然可以!可以通过属性传递值。比如:
<product-card title="iPhone 15" price="7999"></product-card>
在组件内获取属性的方式如下:
constructor() {
super();
const title = this.getAttribute('title');
const price = this.getAttribute('price');
}
还可以监听属性变化(需要用到 observedAttributes() 和 attributeChangedCallback() 方法)
❓Q3:怎么调试 Web Component?
答:右键点击元素 → “检查”,可以看到 Shadow DOM 的结构和样式。调试方式和普通元素无异。
❓Q4:Web Component 可以动态更新内容吗?
答:可以的!只要操作 Shadow DOM 中的元素即可。比如:
this.shadowRoot.getElementById('result').textContent = '新内容';
学习建议:下一步该学什么?
恭喜你已经完成了入门学习!接下来的学习路径建议如下:
初级阶段:
- ✅ 继续练习更多组件(如按钮、分页、弹窗等)
- ✅ 学会使用插槽(
<slot>)机制,允许用户向组件中插入自定义内容 - ✅ 掌握组件间通信方法(如自定义事件
dispatchEvent)
中级进阶:
- ✅ 探索 Web Component 与主流框架结合的方法(如集成到 Vue 或 React 中)
- ✅ 使用构建工具(如 Vite、Rollup)打包组件库
- ✅ 发布你的组件包到 npm 上
推荐资源:
- MDN Web Docs:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
- W3C 规范文档
- Web Components Playground 工具(可在浏览器中实时预览)
结语:开始你的组件之旅吧!
Web Components 是现代前端开发的重要趋势之一,它不依赖任何框架,却拥有极强的灵活性和可维护性。无论你是个人开发者,还是企业团队的一员,掌握这项技能都能提升你的开发效率和组件管理能力。
现在你已经学会了如何创建一个组件、如何使用 Shadow DOM 隔离样式、以及如何构建一个完整的天气组件。相信你已经对 Web Components 充满了信心!
记住一句话:写一次,用百次;组件化,才是未来!💪
如果你觉得这篇教程对你有帮助,欢迎收藏+分享,也欢迎留言告诉我你希望了解哪些 Web Components 高级技巧 😊

评论 0