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

低调写码
2025-06-13 23:45
阅读 426

开篇:Web Components 是什么?

开篇:Web Components 是什么?

你有没有想过,在网页上复用一段功能完整的界面组件(比如按钮、输入框、导航栏)有多麻烦?通常我们都要借助像 React 或 Vue 这样的框架来做这件事。

但其实,浏览器本身已经原生支持了一种叫做 Web Components 的方式,让我们可以像使用 <button><input> 一样,创建和使用自定义的 HTML 元素!

🎯 简单一句话:Web Components 是一种浏览器原生支持的技术,让我们能够自定义 HTML 元素,并像普通 HTML 标签一样使用它们。

这有什么好处呢?

  • 📦 模块化开发:可以将功能封装成一个个独立组件
  • 🧩 跨项目复用:写一次组件,多个项目都可以用
  • 无需依赖框架:没有 React/Vue,也能实现“组件化”

接下来我们就从零开始,一步步带你走进这个全新的世界!


环境准备:搭建你的第一个 Web Components 环境

环境准备:搭建你的第一个 Web Components 环境

所需工具

要开始学习 Web Components,你只需要一个现代浏览器(推荐 Chrome),以及一个代码编辑器。

🔧 必备工具:

工具 说明
浏览器 推荐 Chrome 或 Edge(对 Web Components 支持最好)
编辑器 VS Code(免费,功能强大)
HTTP 服务 可选,为了方便测试,推荐安装 live-server

安装步骤

步骤 1:下载并安装 VS Code

👉 地址:https://code.visualstudio.com/
安装完成后打开即可。

步骤 2:安装 Live Server 插件

VS Code 中点击左侧扩展图标 → 搜索 “Live Server” → 安装插件

步骤 3:创建项目文件夹

新建一个文件夹,比如叫 web-components-tutorial

结构如下:

web-components-tutorial/
│
├── index.html
└── main.js

然后右键点击 index.html 文件,选择 “Open with Live Server”,就可以在浏览器中运行了 ✅


核心概念:一文讲透 Web Components 的三个关键技术

核心概念:一文讲透 Web Components 的三个关键技术

Web Components 不是一个单独的技术,而是由三个主要技术组成的“组合拳”。理解这三个核心技术,你就理解了 Web Components 的核心思想。

1. 自定义元素(Custom Elements)

你可以定义自己的 HTML 元素,例如 <my-button>,它本质上是一个 JavaScript 类。

// main.js
class MyButton extends HTMLElement {
  constructor() {
    super();
    this.innerHTML = "我是自定义按钮";
  }
}

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

HTML 使用方法:

<!-- index.html -->
<my-button></my-button>

💡 小提示:标签名必须包含一个短横线 -,比如 my-button,不能是 mybutton


2. Shadow DOM(影子 DOM)

Shadow DOM 让我们可以把组件内部的样式和结构与外部页面隔离,避免冲突。

// main.js
class MyInput extends HTMLElement {
  constructor() {
    super();
    
    // 创建一个 Shadow Root
    const shadow = this.attachShadow({ mode: 'open' });
    
    // 添加内容和样式
    const input = document.createElement('input');
    input.setAttribute('type', 'text');
    input.placeholder = '请输入内容';

    const style = document.createElement('style');
    style.textContent = `
      input {
        border: 1px solid #4CAF50;
        padding: 8px;
        font-size: 16px;
        width: 200px;
      }
    `;

    shadow.appendChild(style);
    shadow.appendChild(input);
  }
}

customElements.define("my-input", MyInput);

HTML 使用方法:

<my-input></my-input>

🎯 效果:即使你整个网站有别的 input 样式,这个组件的样式也不会被影响!


3. 模板标签(HTML Templates)

我们可以使用 <template> 标签来定义组件模板,这样可以更清晰地组织结构。

<!-- index.html -->
<template id="greeting-template">
  <style>
    .greet {
      color: blue;
      font-size: 20px;
    }
  </style>
  <div class="greet">你好,Web Components!</div>
</template>

<script src="main.js"></script>

对应的 JS 代码:

// main.js
class GreetingComponent extends HTMLElement {
  constructor() {
    super();

    const template = document.getElementById("greeting-template");
    const shadowRoot = this.attachShadow({ mode: 'open' });
    shadowRoot.appendChild(template.content.cloneNode(true));
  }
}

customElements.define("greeting-component", GreetingComponent);

HTML 使用方法:

<greeting-component></greeting-component>

实战项目:构建一个可复用的 todo-item 组件

实战项目:构建一个可复用的 todo-item 组件

我们来实战开发一个待办事项列表中的单项条目组件,体验完整的 Web Components 构建过程。

目标效果

展示一个带有删除按钮的条目,如:

- 学习 Web Components [X]

Step 1:创建 HTML 结构

<!-- index.html -->
<template id="todo-item-template">
  <style>
    .item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: #f4f4f4;
      padding: 10px;
      margin-bottom: 5px;
      border-radius: 4px;
    }

    .delete-btn {
      background: red;
      color: white;
      border: none;
      padding: 5px 10px;
      cursor: pointer;
      border-radius: 3px;
    }
  </style>

  <div class="item">
    <slot name="content"></slot>
    <button class="delete-btn">X</button>
  </div>
</template>

Step 2:编写 JS 类逻辑

// main.js
class TodoItem extends HTMLElement {
  constructor() {
    super();

    const template = document.getElementById("todo-item-template");
    const shadowRoot = this.attachShadow({ mode: 'open' });

    shadowRoot.appendChild(template.content.cloneNode(true));

    const button = shadowRoot.querySelector('.delete-btn');
    button.addEventListener('click', () => {
      this.remove(); // 删除自己
    });
  }
}

customElements.define("todo-item", TodoItem);

Step 3:在页面中使用组件

<!-- index.html -->
<body>
  <todo-item><span slot="content">完成教程作业</span></todo-item>
  <todo-item><span slot="content">预习明天课程内容</span></todo-item>
</body>

✅ 最终效果:你会看到两个带删除功能的待办项!


常见问题解答(FAQ)

❓ Q1:为什么我的组件不显示?

✔️ 可能原因:

  • 没有正确调用 customElements.define
  • 组件名称没有短横线,比如用了 mybutton 而不是 my-button
  • HTML 中没有引入 main.js

✅ 解决办法: 检查控制台是否有报错信息,确保 JS 正确执行。


❓ Q2:组件内 CSS 样式不起作用?

✔️ 原因可能是:

  • 样式没放在 Shadow DOM 内部
  • 漏掉了 mode: 'open' 导致无法访问

✅ 解决办法: 确保样式插入到 shadowRoot,或者使用 <template> 引入。


❓ Q3:如何传递参数给组件?

💡 方法有两种:

  1. 通过 Attributes 设置

    <my-component title="标题"></my-component>
    

    JS 中获取:

    const title = this.getAttribute('title');
    
  2. 使用 observedAttributes 配合监听变化

    static get observedAttributes() {
      return ['title'];
    }
    
    attributeChangedCallback(name, oldValue, newValue) {
      if (name === 'title') {
        console.log('title changed to:', newValue);
      }
    }
    

学习建议:下一步该学什么?

恭喜你完成了第一个 Web Components 组件!接下来你可以继续深入以下方向:

✅ 推荐学习路径

学习内容 说明
深入 Shadow DOM 学习 Shadow DOM 高级特性,如继承、事件冒泡
使用属性传值 掌握 Attribute 和 Properties 的区别
生命周期回调 connectedCallback, disconnectedCallback
组件间通信 如何让组件之间互相通信或触发事件
结合现有框架 如何在 React/Vue 中使用 Web Components
工程化打包 使用 Rollup/Webpack 打包组件库

前端开发工具界面-1

📌 推荐资源:


总结:开启属于你的组件化开发旅程

本教程为你打开了 Web Components 的大门,它是一门真正“原生”的组件化技术,适合希望摆脱框架限制或构建高度可复用组件的开发者。

📌 回顾关键点:

  • Web Components 由 Custom Elements + Shadow DOM + Template 组成
  • 组件可以像 HTML 标签一样使用
  • 不需要依赖任何框架,完全原生
  • 学会后可以在任何前端项目中通用

现在就动手实践吧,别忘了多试几个小项目练手,比如做一个菜单组件、一个数据表格组件等。你也可以尝试将 Web Components 应用于实际工作中,提升效率!

祝你学习愉快,成为 Web 组件化开发高手!🚀

评论 0

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