微前端技术之Web Components

server/2024/9/24 11:09:42/

Web Component 是一套技术,允许你创建可重用定制的元素(它们的功能封装在你的代码之外)并且在你的web应用中使用它们。通俗来讲就是将部分可重用的代码抽离,封装成一个独立的组件,方便在其他地方引用。
Web components旨在解决这个问题,它有三项主要技术组成,它们可以一起使用来创建封装功能的定制元素。

  • Custom element (自定义元素) :一组JavaScript API,允许你定义custom elements及其行为,然后可以在你的用户界面中按需使用它们。
  • Shadow DOM(影子 Dom):一组JavaScript API ,用于将封装的影子DOM树附加到元素(与主文档Dom分开呈现)并控制器关联功能。通过这种方式,可以保持元素的功能私有,这样他们就可以被脚本化和样式化,二不用担心与文档的其他部分冲突。
  • HTML template (HTML 模版):和元素使你可以编写不在呈现页面中显示的标记模版。它们可以作为自定义元素结构被多次重用。

实现web component 的基本方法如下:

  1. 创建一个类或函数来指定 web 组件的功能,如果使用类,请使用 ECMAScript 2015 的类语法 (参阅类获取更多信息)。
  2. 使用 CustomElementRegistry.define() 方法注册你的新自定义元素,并向其传递要定义的元素名称、指定元素功能的类、以及可选的其所继承自的元素。
  3. 如果需要的话,使用 Element.attachShadow() 方法将一个 shadow DOM 附加到自定义元素上。使用通常的 DOM 方法向 shadow DOM 中添加子元素、事件监听器等等。
  4. 如果需要的话,使用 和 定义一个 HTML 模板。再次使用常规 DOM 方法克隆模板并将其附加到你的 shadow DOM 中。
  5. 在页面任何你喜欢的位置使用自定义元素,就像使用常规 HTML 元素那样。

自定义元素

自定义元素的类型

有两种类型的自定义元素:

  • 自定义内置元素(Customized built-in element)继承自标准的 HTML 元素,例如 HTMLImageElement 或 HTMLParagraphElement。它们的实现定义了标准元素的行为。
  • 独立自定义元素(Autonomous custom element)继承自 HTML 元素基类 HTMLElement。你必须从头开始实现它们的行为。

自定义元素生命周期回调包括:

  • connectedCallback():每当元素添加到文档中时调用。规范建议开发人员尽可能在此回调中实现自定义元素的设定,而不是在构造函数中实现。
  • disconnectedCallback():每当元素从文档中移除时调用。
  • adoptedCallback():每当元素被移动到新文档中时调用。
  • attributeChangedCallback():在属性更改、添加、移除或替换时调用。有关此回调的更多详细信息,请参见响应属性变化。
// 为这个元素创建类
class MyCustomElement extends HTMLElement {static observedAttributes = ["color", "size"];constructor() {// 必须首先调用 super 方法super();}connectedCallback() {console.log("自定义元素添加至页面。");}disconnectedCallback() {console.log("自定义元素从页面中移除。");}adoptedCallback() {console.log("自定义元素移动至新页面。");}attributeChangedCallback(name, oldValue, newValue) {console.log(`属性 ${name} 已变更。`);}
}customElements.define("my-custom-element", MyCustomElement);
注册自定义元素

要使自定义元素在页面中可用,请调用 Window.customElements 的 define() 方法。
define() 方法接受以下参数:

  • name
    元素的名称。必须以小写字母开头,包含一个连字符,并符合规范中有效名称的定义中列出的一些其他规则。
  • constructor
    自定义元素的构造函数。
  • options
    仅对于自定义内置元素,这是一个包含单个属性 extends 的对象,该属性是一个字符串,命名了要扩展的内置元素。
customElements.define("word-count", WordCount, { extends: "p" });
使用自定义元素
//要使用自定义内置元素,请使用内置元素,但将自定义名称作为 is 属性的值:
<p is="word-count"></p>
//要使用独立自定义元素,就像使用内置的 HTML 元素一样,使用自定义名称即可:
<popup-info><!-- 元素的内容 -->
</popup-info>

影子 DOM

自定义元素的一个重要方面是封装,因为自定义元素从定义上来说是一种可重用功能:它可以被放置在任何网页中,并且期望它能够正常工作。因此,很重要的一点是,运行在页面中的代码不应该能够通过修改自定义元素的内部实现而意外地破坏它。影子 DOM(Shadow DOM)允许你将一个 DOM 树附加到一个元素上,并且使该树的内部对于在页面中运行的 JavaScript 和 CSS 是隐藏的。

创建一个影子 DOM

<div id="host"></div>
<span>I'm not in the shadow DOM</span>

我们将使用 “host” 元素作为影子宿主。我们调用宿主上的 attachShadow() 来创建影子 DOM,然后可以像我们将节点添加到主 DOM 一样将节点添加到影子 DOM 中。在这个示例中,我们添加了单个 元素:

const host = document.querySelector("#host");
const shadow = host.attachShadow({ mode: "open" });
const span = document.createElement("span");
span.textContent = "I'm in the shadow DOM";
shadow.appendChild(span);

结果看起来像这样:

I’m in the shadow DOM
I’m not in the shadow DOM

在上面的例子中,我们将一个参数 { mode: “open” } 传入 attachShadow()。当 mode 设置为 “open” 时,页面中的 JavaScript 可以通过影子宿主的 shadowRoot 属性访问影子 DOM 的内部。

使用模板和插槽

当你必须在网页上复用相同的标记结构时,使用某种模板而不是一遍又一遍地重复相同的结构是有意义的。以前也可以实现这一点,但 HTML 元素使得这个过程更加简单。此元素及其内容不会在 DOM 中渲染,但仍可使用 JavaScript 引用它。
定义一个简单的模版

<template id="my-paragraph"><p>我的段落</p>
</template>

在DOM中使用模版

let template = document.getElementById("my-paragraph");
let templateContent = template.content;
document.body.appendChild(templateContent);

Web Component中使用模版

模板本身就很有用,但与 web 组件一起使用效果更好。让我们定义一个名为 的 web 组件,使用模板作为其影子 DOM 的内容:

customElements.define("my-paragraph",class extends HTMLElement {constructor() {super();let template = document.getElementById("my-paragraph");let templateContent = template.content;const shadowRoot = this.attachShadow({ mode: "open" });shadowRoot.appendChild(templateContent.cloneNode(true));}},
);

使用Web Component

<my-paragraph></my-paragraph>

http://www.ppmy.cn/server/23183.html

相关文章

Shader实战(3):贴图像素化风格实现

话不多说&#xff0c;将以下shader赋给材质贴上贴图即可。 Shader "HQY/Shader2" //自己改名 {Properties{_Diffuse ("Diffuse", Color) (1,1,1,1)_MainTex ("MainTex", 2D) "white" {}_Specular("Specular", Color) (…

git版本控制基础工作流

版本控制基础工作流 注意&#xff1a;在进行分支切换和合并操作前&#xff0c;建议先确保当前分支上的修改已经提交或保存&#xff0c;避免意外丢失代码。 在解决冲突时&#xff0c;可以根据实际情况选择其他辅助工具&#xff0c;如图形化界面工具或第三方合并工具。这些工具可…

jenkins搭建

安装jdk yum install -y java-1.8.0-openjdk.x86_64 默认安装到usr/lib/jvm目录下 查看JDK信息,输入命令:java -version 检测JDK安装包,输入命令:rpm -qa | grep java 进入安装目录。 输入命令:cd /usr/lib/jvm 删除Java相关文件,输入命令:rm -rf /usr/lib/jvm 配置…

spring boot 将配置文件信息 赋值到类注解

如何将application.properties中的值赋值给一个类注解呢 先看两个类 application.properties server.port8080 flow.namemyFlow flow.age20Component Documented Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) public interface UserInfo {String name() d…

谷歌TPU(Tensor Processing Unit)

谷歌TPU&#xff08;Tensor Processing Unit&#xff09; https://cloud.google.com/tpu/docs/intro-to-tpu?hlzh-cn CPU的工作模式和GPU工作模式的区别 CPU 最大的优点是它们的灵活性。您可以在 CPU 上为许多不同类型的应用加载任何类型的软件。对于每次计算&#xff0c;CPU…

WPS-EXCEL:快速删除多个线条对象

问题图 我需要将线条快速删除 方法一:使用定位对象功能 使用定位功能&#xff1a;按Ctrl G打开定位对话框。在对话框中&#xff0c;点击“定位条件”。 定位对象&#xff1a;在定位条件对话框中&#xff0c;勾选“对象”选项&#xff0c;然后点击“确定”。这样&#xff0c;…

学习Python的第三天

学习Python的第三天&#xff0c;我开始深入Python的基本语法和特性&#xff0c;并通过编写一些简单的代码来加深理解。以下是我今天学习的一些代码案例&#xff1a; 1. 函数定义与调用 # 定义一个函数&#xff0c;计算两个数的和 def add_numbers(a, b):return a b# 调用函数…

企业微信hook接口协议,ipad协议http,发送小程序

发送小程序 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信send_userid是long要发送的人或群idisRoom是bool是否是群消息 请求示例 {"uuid":"543ed7f3-6ec1-4db8339a140f7","send_userid":788130255…