Web Components:原生组件化开发新趋势

需求之外
2025-06-25 23:00
阅读 550

开篇:Web Components 是什么?能做什么?

开篇:Web Components 是什么?能做什么?

想象一下,你去超市买东西,想做蛋糕。如果你得从面粉、鸡蛋开始一步步做起,那很麻烦。但如果超市里已经有现成的“蛋糕半成品包”,你只需要把它们组合起来就能完成整个蛋糕,是不是更轻松了?

在网页开发中也是一样的道理。Web Components 就像是这样一种“半成品包”——它允许我们创建可重用的网页组件,这些组件就像一个个小零件,可以随时拿出来组装到任何网页中。

而且最重要的是:它不需要依赖任何框架(比如 Vue 或 React),而是直接使用浏览器自带的能力来实现的!

一句话总结:Web Components 是一项基于浏览器原生特性的技术,用来创建和复用自定义的 HTML 标签。


环境准备:搭建开发环境

环境准备:搭建开发环境

在开始学习之前,你需要准备好一个最基础的开发环境。

✅ 所需工具列表:

  • 一台电脑(Windows、Mac 或 Linux 都行)
  • 浏览器(推荐 Chrome 或 Firefox)
  • 文本编辑器(推荐 VS Code)
  • 基础的 HTML/CSS/JavaScript 知识(不用担心太深,有基础就行)

🧰 操作步骤:

  1. 安装 VS Code

  2. 创建项目文件夹

    • 在你的电脑上新建一个文件夹,比如 web-components-demo
  3. 在 VS Code 中打开该文件夹

    • 启动 VS Code -> 文件菜单 -> 打开文件夹 -> 选择你刚刚创建的文件夹
  4. 创建一个测试 HTML 文件

    • 右键点击空白处 -> 新建文件 -> 输入 index.html
  5. 写入如下内容作为测试代码:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Web Components 初体验</title>
</head>
<body>
    <h1>Hello, Web Components!</h1>
    <script src="demo.js"></script>
</body>
</html>

现代网页界面设计示例-1

  1. 再创建一个 JS 文件 demo.js
    • 在同一个目录下新建文件,输入以下代码即可:
console.log("Hello from JavaScript");
  1. 用浏览器打开这个 HTML 文件
    • 直接右键 index.html -> 使用浏览器打开
    • 打开控制台(F12 或右键页面选择“检查”)可以看到输出的信息

✅ 成功!你现在有了一个简单的开发环境,接下来就可以开始学习 Web Components 的核心知识啦!


核心概念:什么是 Web Components?

核心概念:什么是 Web Components?

Web Components 其实包含三大核心技术:

技术名称 作用
自定义元素(Custom Elements) 创建自己的 HTML 标签,例如 <my-button>
阴影 DOM(Shadow DOM) 让组件内部的结构与样式与外部隔离,互不干扰
HTML 模板(HTML Templates) 为组件定义可复用的结构模板

我们来分别理解这三个概念,并配上示例。


🌱 1. 自定义元素(Custom Elements)

这是 Web Components 的核心之一。我们可以像定义 divspan 一样定义自己的标签。

示例:创建一个 <hello-world> 组件

// demo.js

class HelloWorld extends HTMLElement {
    constructor() {
        super(); // 必须写这句
        this.innerHTML = "你好,世界!";
    }
}

customElements.define('hello-world', HelloWorld);

然后我们在 HTML 中使用它:

<hello-world></hello-world>

刷新页面,你应该看到 “你好,世界!” 出现在页面上。

🔍 新手提问:为什么要继承 HTMLElement

这是因为所有 HTML 元素本质上都是这个类的子类。我们要创建自定义标签,就必须让它具备基本的 HTML 元素行为。


🎭 2. 阴影 DOM(Shadow DOM)

Shadow DOM 的最大特点就是封装能力 —— 它让组件内的样式和结构对外隐藏,不会被全局样式干扰。

示例:用 Shadow DOM 封装一个按钮组件

// demo.js

class MyButton extends HTMLElement {
    constructor() {
        super();
        
        const shadow = this.attachShadow({ mode: 'open' });
        
        // 创建按钮元素
        const button = document.createElement('button');
        button.textContent = '点我';
        button.style.backgroundColor = 'lightblue';
        button.style.borderRadius = '5px';

        // 添加事件监听器
        button.addEventListener('click', () => {
            alert('你点了按钮!');
        });

        // 把按钮插入到 shadow DOM 中
        shadow.appendChild(button);
    }
}

customElements.define('my-button', MyButton);

使用方式:

<my-button></my-button>

效果:你会看到一个蓝色按钮,点击会有弹窗提示,但它的样式不会影响你页面上的其他按钮。

🔍 新手提问:什么是模式(mode)?openclosed 有什么区别?

  • open:shadow root 可以通过 JS 获取(方便调试和访问)
  • closed:不能通过 JS 获取,更加封闭(适合封装性要求高的场景)

📄 3. HTML 模板(Templates)

如果每次都要手动创建元素,写一大堆 DOM 操作,就显得比较笨拙了。这时候我们可以使用 <template> 标签来提前写好结构。

示例:使用模板创建一个卡片组件

<!-- index.html -->
<template id="card-template">
    <style>
        .card {
            border: 1px solid #ccc;
            padding: 10px;
            margin: 10px;
            width: 200px;
        }
    </style>
    <div class="card">
        <h3>默认标题</h3>
        <p>这里是默认内容</p>
    </div>
</template>

然后用 JS 加载模板:

// demo.js

class MyCard extends HTMLElement {
    constructor() {
        super();

        const template = document.getElementById('card-template');
        const content = template.content.cloneNode(true); // true 表示复制全部子节点

        const shadow = this.attachShadow({ mode: 'open' });
        shadow.appendChild(content);
    }
}

customElements.define('my-card', MyCard);

使用方式:

<my-card></my-card>

效果:你会看到一个带有样式的卡片,且样式只在这个组件内部生效。


实战项目:做一个带标题和内容的卡片组件

实战项目:做一个带标题和内容的卡片组件

现在我们来实战制作一个完整的组件,功能包括:

  • 支持设置标题和内容
  • 每次点击展开或收起内容

🔧 第一步:编写 HTML 模板

<!-- index.html -->
<template id="expander-card">
    <style>
        .card {
            border: 1px solid #ddd;
            padding: 10px;
            margin: 10px;
            max-width: 300px;
            cursor: pointer;
        }
        .content {
            display: none;
        }
    </style>


![JavaScript框架对比-2](https://code-guide.oss.shanghai.autogptai.club/common/file/download?name=date2025062523/00089567-6d76-4dc6-9ad7-8153b3efee99.jpg)


    <div class="card">
        <h3 id="title">标题</h3>
        <div id="content" class="content">
            <p>这里是隐藏的内容区域。</p>
        </div>
    </div>
</template>

💻 第二步:用 JS 创建组件

// demo.js

class ExpanderCard extends HTMLElement {
    constructor() {
        super();

        const template = document.getElementById('expander-card');
        const content = template.content.cloneNode(true);

        const shadow = this.attachShadow({ mode: 'open' });
        shadow.appendChild(content);

        // 获取 shadow 内部的元素
        const title = shadow.querySelector('#title');
        const contentDiv = shadow.querySelector('#content');

        // 设置标题和内容(来自自定义属性)
        title.textContent = this.getAttribute('title') || '默认标题';
        contentDiv.querySelector('p').textContent = this.getAttribute('content') || '默认内容';

        // 点击切换显示/隐藏
        const card = shadow.querySelector('.card');
        let visible = false;

        card.addEventListener('click', () => {
            visible = !visible;
            contentDiv.style.display = visible ? 'block' : 'none';
        });
    }
}

customElements.define('expander-card', ExpanderCard);

🎯 第三步:使用组件

<expander-card title="我是标题" content="点击展开详细信息"></expander-card>

刷新页面,点击卡片试试看吧!


常见问题:新手易犯错误及解答

❓1. 为什么我的自定义标签不显示?

可能原因:

  • 没有正确调用 customElements.define
  • 类名没写对或拼写错了
  • 标签名必须包含短横线(如 my-card 而不是 mycard

✅ 解决办法:检查拼写、语法是否正确。


❓2. 组件样式为什么失效了?

可能原因:

  • 样式未放进 shadow DOM
  • 外部样式污染了组件样式

✅ 解决办法:将样式写在 <template> 内或者直接添加到 shadow DOM。


❓3. 如何给组件传参数?

可以通过 HTML 属性传递数据,比如:

<my-component data-name="Tom"></my-component>

然后在 JS 中用 this.getAttribute('data-name') 获取。


学习建议:下一步可以学什么?

掌握 Web Components 后,你可以考虑以下几个方向继续深入学习:

🧭 方向一:结合框架使用(Vue / React / Angular)

虽然 Web Components 本身是原生的,但它可以在主流前端框架中使用,甚至可以用它构建跨框架的组件库。

🔗 推荐资源:

💡 方向二:尝试开发自己的组件库

试着做出一些通用组件:按钮、输入框、导航条等,慢慢积累一个自己的“组件包”。

🚀 方向三:了解现代 Web 开发最佳实践

学习如何打包组件、部署上线,以及如何用工具管理多个组件(比如使用 npm 发布组件)。


恭喜你完成了第一篇 Web Components 入门教程!希望你能动手跟着练习一遍,理解每个知识点背后的原理。接下来的学习会越来越有趣,加油!

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝