怎样利用Web Components构建跨框架复用的业务组件?

来源:网站主作者:松本一香头衔:网络博主
导读:本期聚焦于小伙伴创作的《怎样利用Web Components构建跨框架复用的业务组件?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《怎样利用Web Components构建跨框架复用的业务组件?》有用,将其分享出去将是对创作者最好的鼓励。

Web Components是一套由浏览器原生支持的组件化标准,包含Custom Elements、Shadow DOM、HTML Templates、HTML Imports四个核心技术,其中前三个是目前主流浏览器均已支持的特性,能够帮助我们构建不依赖任何前端框架的独立组件,实现跨框架复用。

怎样利用Web Components构建跨框架复用的业务组件?

Web Components核心技术介绍

Custom Elements 自定义元素

自定义元素允许我们注册新的HTML标签,浏览器会识别这些标签并触发对应的生命周期回调,我们可以在回调中定义组件的逻辑。注册自定义元素需要使用customElements.define方法,第一个参数是标签名,要求必须包含连字符,第二个参数是组件的类,该类需要继承HTMLElement

Shadow DOM 影子DOM

Shadow DOM能够为组件创建独立的DOM和样式作用域,组件内部的DOM结构和样式不会影响到外部页面,外部页面的样式也不会侵入组件内部,完美实现组件的隔离。我们可以通过元素的attachShadow方法开启Shadow DOM,参数为{ mode: 'open' }表示外部可以通过元素的shadowRoot属性访问影子DOM。

HTML Templates 模板

HTML模板使用template标签定义,模板中的内容不会在页面加载时渲染,只有在被克隆并插入到DOM中时才会生效,适合用来定义组件的内部结构,我们可以提前写好模板,在组件初始化时克隆模板内容插入到Shadow DOM中。

构建跨框架复用的业务组件示例

我们以一个简单的用户信息展示业务组件为例,这个组件接收一个用户ID,调用接口获取用户信息并展示,同时支持自定义展示样式,接下来逐步实现这个组件。

第一步:定义组件模板

首先在HTML中定义组件的模板,包含基本的结构和默认样式:

<template id="user-info-template">
  <style>
    .user-card {
      border: 1px solid #e5e5e5;
      border-radius: 8px;
      padding: 16px;
      width: 300px;
      font-family: sans-serif;
    }
    .user-name {
      font-size: 18px;
      font-weight: bold;
      margin-bottom: 8px;
    }
    .user-email {
      color: #666;
      font-size: 14px;
    }
    .loading {
      color: #999;
    }
  </style>
  <div class="user-card">
    <div class="user-name"></div>
    <div class="user-email"></div>
  </div>
</template>

第二步:定义自定义元素类

接下来定义组件的类,继承HTMLElement,在构造函数中初始化Shadow DOM,克隆模板内容插入,同时定义组件的生命周期和属性监听逻辑:

class UserInfoCard extends HTMLElement {
  constructor() {
    super();
    // 开启Shadow DOM
    this.attachShadow({ mode: 'open' });
    // 获取模板并克隆内容
    const template = document.getElementById('user-info-template');
    const content = template.content.cloneNode(true);
    this.shadowRoot.appendChild(content);
    // 获取内部DOM元素
    this.nameEl = this.shadowRoot.querySelector('.user-name');
    this.emailEl = this.shadowRoot.querySelector('.user-email');
    this.cardEl = this.shadowRoot.querySelector('.user-card');
  }

  // 定义需要监听的属性
  static get observedAttributes() {
    return ['user-id', 'theme-color'];
  }

  // 属性变化时的回调
  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'user-id' && newValue) {
      this.fetchUserInfo(newValue);
    }
    if (name === 'theme-color' && newValue) {
      this.cardEl.style.borderColor = newValue;
    }
  }

  // 组件插入到DOM时的回调
  connectedCallback() {
    const userId = this.getAttribute('user-id');
    if (userId) {
      this.fetchUserInfo(userId);
    }
  }

  // 获取用户信息的方法
  async fetchUserInfo(userId) {
    try {
      this.nameEl.textContent = '加载中...';
      this.emailEl.textContent = '';
      // 模拟接口请求,实际项目中替换为真实接口地址
      const response = await fetch(`https://ipipp.com/api/user/${userId}`);
      const user = await response.json();
      this.nameEl.textContent = user.name;
      this.emailEl.textContent = user.email;
    } catch (error) {
      this.nameEl.textContent = '加载失败';
      this.emailEl.textContent = '';
    }
  }
}

第三步:注册自定义元素

使用customElements.define方法注册组件,之后就可以在任意页面中使用这个标签:

customElements.define('user-info-card', UserInfoCard);

在不同框架中使用该组件

由于Web Components是浏览器原生支持的,所以可以在任何前端框架中直接使用,不需要额外的适配。

在原生HTML中使用

直接在HTML中写入标签即可,通过属性传递参数:

<user-info-card user-id="1001" theme-color="#1890ff"></user-info-card>

在Vue中使用

Vue默认支持自定义元素,不需要额外配置,直接在模板中使用:

<template>
  <div>
    <user-info-card :user-id="userId" theme-color="#52c41a"></user-info-card>
  </div>
</template>

<script>
export default {
  data() {
    return {
      userId: '1002'
    };
  }
};
</script>

在React中使用

React中也可以直接使用自定义元素,注意属性名如果是驼峰式需要转换为连字符形式,或者通过元素的setAttribute方法设置:

import React from 'react';

function App() {
  const userId = '1003';
  return (
    <div>
      <user-info-card user-id={userId} theme-color="#fa541c"></user-info-card>
    </div>
  );
}

export default App;

在Angular中使用

Angular需要在模块中配置CUSTOM_ELEMENTS_SCHEMA来允许使用自定义元素:

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  bootstrap: [AppComponent]
})
export class AppModule {}

之后在组件的模板中直接使用:

<user-info-card user-id="1004" theme-color="#722ed1"></user-info-card>

注意事项

  • 自定义元素的标签名必须包含连字符,避免和原生HTML标签冲突。
  • 如果组件需要支持表单场景,需要实现相关的表单关联API,比如FormAssociated接口。
  • 旧版本浏览器(如IE)不支持Web Components,如果需要兼容可以使用对应的polyfill库。
  • 组件内部的事件需要通过自定义事件派发出去,外部框架才能监听到,比如组件内部触发this.dispatchEvent(new CustomEvent('user-load', { detail: user })),外部就可以通过addEventListener监听这个事件。

Web_Components跨框架复用业务组件自定义元素修改时间:2026-07-13 23:24:13

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。