关于Web Component

2024年8月14日

引言

Web Component 是一种用于构建可复用用户界面组件的技术,开发者可以创建自定义的 HTML 标签,并将其封装为包含逻辑和样式的独立组件,从而在任何 Web 应用中重复使用,并且可以做到无框架跨框架。

不同于 Vue/React 等社区或厂商的组件化开发方案,Web Component 被定义在标准的 HTML 和 DOM 标准中。它由一组相关的 Web 平台 API 组成,也可以与现有的前端框架和库配合使用Web Component 的兼容性良好,可以在现代浏览器中直接使用,也可以通过 polyfill 兼容到旧版浏览器。

每个 Web Component 都具有自己的 DOM 和样式隔离,避免了全局 CSS 和 JavaScript 的冲突问题。它还支持自定义事件和属性,可以与其他组件进行通信和交互。实现这些主要基于其三个技术:

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

如何简单创建一个Web Components

挂载

首先为这个项目创建一个文件夹,然后在里面为组件准备一个button.js文件,在这里将编写一个按钮组件,button.js文件内容如下:

  1. 模版
let templateTemp = `
<template id='button'><div class="button">按钮</div>
</template>
`;
  1. 样式
let styleTemp = `
.button{width:70px;height:50px;background-color:rgb(54, 54, 252);color: white;display: flex;justify-content: center;align-items: center;border-radius: 10px;user-select: none;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;cursor: pointer;
}
.button:hover{background-color:rgb(38, 38, 250);
}
.button:active{background-color:rgb(5, 5, 255);
}`;
  1. 将模版字符串转化为document节点
const parser = new DOMParser();
const doc = parser.parseFromString(templateTemp, "text/html");
const temp = doc.getElementById("button");
  1. 创建自定义组件
class button extends HTMLElement {constructor() {super();//创建一个影子节点,组件会挂载在上面,参数mode表示是否可被外部访问const shadow = this.attachShadow({ mode: "open" });//获取模版和样式const content = temp.content.cloneNode(true);const style = document.createElement("style");style.textContent = styleTemp;//挂载shadow.appendChild(style);shadow.append(content);}
}
customElements.define("zf-button", button);
  1. 接下来查看这个组件,比如在一个原生的index.html文件中
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><link rel="icon" type="svg+xml" href="public/logo.svg"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>My HTML File</title><link rel="stylesheet" type="text/css" href="style.css"><script src="script.js"></script>//导入文件<script src="button.js"></script>
</head>
<body>//直接使用模版<zf-button></zf-button>
</body>
</html>

这样一个简单的Web Component就挂载好了并且可以看到了。
在这里插入图片描述
现在这个按钮已经有最基本的样式,但相比Element组件库的按钮还不够丰富,比如按钮的类型,或大或小的,在用这个组件时可以以参数的方式进行切换,还有颜色等等,这些就涉及如何与组件通讯了,还有想让按钮有个图标,这样就要用到插槽。在处理这些问题前,先来了解Web Component的生命周期。


生命周期

一个Web Component有4个生命周期

  1. connectedCallback
    首次插入文档DOM时调用,这个回调函数通常用于执行一些初始化操作,比如添加事件监听器、请求数据等等。在这个时候,元素已经被添加到了文档中,可以访问到this.shadowRoot里的 DOM 和其他元素。
  2. disconnectedCallback
    从文档删除时调用,这个回调函数通常用于清理一些资源,比如取消事件监听器、停止定时器等等。在这个时候,元素已经不再被文档所包含,无法访问到 DOM 和其他元素。
  3. adoptedCallback
    移动到新文档时调用,这个回调函数通常用于处理一些文档级别的操作,比如重新计算布局(重排)、修改样式等等。在这个时候,元素已经从原来的文档中移除,并被添加到了新的文档中。
  4. attributeChangedCallback
    修改自身属性时调用,这个回调函数通常用于处理一些属性相关的逻辑,比如根据属性值的变化更新元素的样式、重新渲染元素等等。在这个时候,元素的属性已经被修改,可以通过新的属性值来进行相应的处理。
class button extends HTMLElement {constructor() {super();}connectedCallback() {console.log("首次插入文档");}disconnectedCallback() {console.log("从文档删除");}adoptedCallback() {console.log("移动到新文档");}attributeChangedCallback() {console.log("修改");}
}

组件通讯

组件通讯主要就是外部传递信息给组件内部和组件内部传递信息给外部。主要的实现在于shadowRoot的方法去操作组件的自定义属性。比如想要修改刚才按钮组件的文字,那么给组件添加自定义属性text:

<zf-button text="添加"></zf-button>

然后在生命周期connectedCallback中获取并赋值

connectedCallback() {if (this.hasAttribute("text")) {this.shadowRoot.querySelector(".button").innerHTML =this.getAttribute("text");}
}

再或者想要点击这个按钮后,文字变为修改,这个就得在生命周期attributeChangedCallback去监听text属性,如果有huan hu。
首先要添加observedAttributes数组,元素为自定义属性的名字,这样attributeChangedCallback才能监听。

static observedAttributes = ["text"];

接着在attributeChangedCallback,监听到text的变化,然后在shadowRoot中找到按钮组件进行修改。

attributeChangedCallback(name, oldValue, newValue) {if (name === "text") {this.shadowRoot.querySelector(".button").innerHTML =newValue;}
}

最后就是外部如何去修改组件的自定义属性,这里需要shadow节点可以被访问

const shadow = this.attachShadow({ mode: "open" });

然后给组件添加点击事件,在里面修改组件的属性值,这样的修改会被组件的attributeChangedCallback函数捕抓。

document.addEventListener("DOMContentLoaded", function () {document.querySelector("#btn").addEventListener("click", function () {document.querySelector("#btn").attributes.text.value = "修改";});
});

用Web Component构建组件库

这样的组件库相比针对Vue的element和针对react的vant,它不会受框架的限制,就是不能享受语言框架带来的便利。比如Vue的响应式属性和事件绑定,在原生的html不具备,然后其组件库也是不能使用的,只能用原生的方法去实现。这样的组件库我找到了:

Quark Design
https://quark-ecosystem.github.io/quarkd-docs/vue/#/

还有一些框架可以自己去搭建Web Component组件库,比如Omi框架,在这里用Web Component搭建的组件库,可以适配vue等语言系统的特性

OMI Web Components
https://omi.cdn-go.cn/home/latest/zh/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySql】实验十六 综合练习:图书管理系统数据库结构

文章目录 创建图书管理系统数据库结构一、创建数据表1.1 book表1.2 reader表1.3 borrow表 二、插入示例数据2.1 向book表插入数据2.2 向reader表插入数据2.3 向borrow表插入数据 三、查询操作3.1 根据语义为借书表borrow的bno列和 rno列建立外键3.2 查询张小海编写的“数据库原…

AutoDL部署视觉大模型llama3.2-vision,从视频中寻找特定目标

注&#xff1a; windows11系统。示例为此项目&#xff1a;https://github.com/win4r/VideoFinder-Llama3.2-vision-Ollama 在当今的人工智能领域&#xff0c;深度学习模型的计算需求日益增长&#xff0c;特别是在处理复杂的视觉任务时&#xff0c;强大的算力往往是实现高效应用…

SHELL笔记(条件测试)

基本概念&#xff1a; 条件测试用于在 Shell 脚本中对各种条件进行判断&#xff0c;根据判断结果来决定是否执行特定的命令或代码块。条件测试可以用于比较数值、字符串&#xff0c;检查文件或目录的属性&#xff0c;以及判断命令的执行结果等。 格式&#xff1a; 格式1&…

JDK、MAVEN与IDEA的安装与配置

1.认识JDK、MAVEN与IDEA JDK 提供了编译和运行Java程序的基本环境。Maven 帮助管理项目的构建和依赖。IDEA 提供了一个强大的开发环境&#xff0c;使得编写、调试和运行Java程序更加高效。 2. 安装与环境配置 2.1 官网地址 选择你需要的版本下载&#xff1a; MAVEN下载传送…

微信小程序-prettier 格式化

一.安装prettier插件 二.配置开发者工具的设置 配置如下代码在setting.json里&#xff1a; "editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml"…

【Mac】未能完成该操作 Unable to locate a Java Runtime

重生之我做完产品经理之后回来学习Data Mining Mac打开weka.jar报错"未能完成该操作 Unable to locate a Java Runtime" 1. 打开终端执行 java -version 指令&#xff0c;原来是没安装 JDK 环境 yyzccnn-mac ~ % java -version The operation couldn’t be comple…

【ArcGIS微课1000例】0127:计算城市之间的距离

本文讲述,在ArcGIS中,计算城市(以地级城市为例)之间的距离,效果如下图所示: 一、数据准备 加载配套实验数据包中的地级市和行政区划矢量数据(订阅专栏后,从私信查收数据),如下图所示: 二、计算距离 1. 计算邻近表 ArcGIS提供了计算点和另外点之间距离的工具:分析…

【WPF】Prism学习(五)

Prism Commands 1.错误处理&#xff08;Error Handling&#xff09; Prism 9 为所有的命令&#xff08;包含AsyncDelegateCommand&#xff09;提供了更好的错误处理。 避免用try/catch包装每一个方法根据不同遇到的异常类型来提供特定的逻辑处理可以在多个命令之间共享错误处…

【element-tiptap】Tiptap编辑器核心概念----结构篇

core-concepts 前言&#xff1a;这篇文章来介绍一下 Tiptap 编辑器的一些核心概念 &#xff08;一&#xff09;结构 1、 Schemas 定义文档组成方式。一个文档就是标题、段落以及其他的节点组成的一棵树。 每一个 ProseMirror 的文档都有一个与之相关联的 schema&#xff0c;…

2024.6使用 UMLS 集成的基于 CNN 的文本索引增强医学图像检索

Enhancing Medical Image Retrieval with UMLS-Integrated CNN-Based Text Indexing 问题 医疗图像检索中&#xff0c;图像与相关文本的一致性问题&#xff0c;如患者有病症但影像可能无明显异常&#xff0c;影响图像检索系统准确性。传统的基于文本的医学图像检索&#xff0…

初识Linux · 信号处理 · 续

目录 前言&#xff1a; 可重入函数 重谈进程等待和优化 前言&#xff1a; 在前文&#xff0c;我们已经介绍了信号产生&#xff0c;信号保存&#xff0c;信号处理的主题内容&#xff0c;本文作为信号处理的续篇&#xff0c;主要是介绍一些不那么重要的内容&#xff0c;第一个…

微信小程序 最新获取用户头像以及用户名

一.在小程序改版为了安全起见 使用用户填写来获取头像以及用户名 二.代码实现 <view class"login_box"><!-- 头像 --><view class"avator_box"><button wx:if"{{ !userInfo.avatarUrl }}" class"avatorbtn" op…

WPF MVVM框架

一、MVVM简介 MVC Model View Control MVP MVVM即Model-View-ViewModel&#xff0c;MVVM模式与MVP&#xff08;Model-View-Presenter&#xff09;模式相似&#xff0c;主要目的是分离视图&#xff08;View&#xff09;和模型&#xff08;Model&#xff09;&#xff0c;具有低…

【算法】【优选算法】前缀和(下)

目录 一、560.和为K的⼦数组1.1 前缀和1.2 暴力枚举 二、974.和可被K整除的⼦数组2.1 前缀和2.2 暴力枚举 三、525.连续数组3.1 前缀和3.2 暴力枚举 四、1314.矩阵区域和4.1 前缀和4.2 暴力枚举 一、560.和为K的⼦数组 题目链接&#xff1a;560.和为K的⼦数组 题目描述&#x…

两大新兴开发语言大比拼:Move PK Rust

了解 Move 和 Rust 的差异有助于开发者根据项目的具体需求选择最合适的语言。选择不恰当的语言可能会导致项目后期出现技术债务。不同语言有其独特的优势。了解 Move 和 Rust 的差异可以帮助开发者拓展技术视野&#xff0c;发现不同语言在不同领域的应用潜力。 咱们直奔主题&a…

Scaling Law的“终结“还是新起点?——开源实践者的深度思考

作者&#xff1a;宋大宝&#xff0c;与大宝同学因那篇《回顾总结展望「融合RL与LLM思想&#xff0c;探寻世界模型以迈向AGI」》结识于今年春天&#xff0c;虽我们当时某些思想观念有些出入&#xff0c;也碰撞出了很多火花与共鸣&#xff0c;并持续地相互启发的走到了现在。他是…

“fc-async”提供了基本的异步处理能力

在开发中,异步处理已经成为提升系统性能和用户体验的常用方式。然而,传统的@Async注解和基础的异步处理工具在面对复杂的任务场景时,存在局限性。这些局限性包括但不限于高并发环境下的稳定性、任务失败后的恢复机制、以及任务的监控和管理。 开源项目“fc-async”提供了基…

Ubuntu 的 ROS 操作系统 turtlebot3 导航仿真

引言 导航仿真是机器人自动化系统中不可或缺的一部分&#xff0c;能够帮助开发者在虚拟环境中测试机器人在复杂场景下的运动与路径规划。 在 Gazebo 仿真环境中&#xff0c;TurtleBot3 配合 ROS 操作系统提供了强大的导航功能。在进行导航仿真时&#xff0c;首先需要准备地图&…

FFmpeg 4.3 音视频-多路H265监控录放C++开发十三.2:avpacket中包含多个 NALU如何解析头部分析

前提&#xff1a; 注意的是&#xff1a;我们这里是从avframe转换成avpacket 后&#xff0c;从avpacket中查看NALU。 在实际开发中&#xff0c;我们有可能是从摄像头中拿到 RGB 或者 PCM&#xff0c;然后将pcm打包成avframe&#xff0c;然后将avframe转换成avpacket&#xff0…

java八股-jvm入门-程序计数器,堆,元空间,虚拟机栈,本地方法栈,类加载器,双亲委派,类加载执行过程

文章目录 PC Register堆虚拟机栈方法区(Metaspace元空间双亲委派机制类加载器 类装载的执行过程 PC Register 程序计数器&#xff08;Program Counter Register&#xff09;是 Java 虚拟机&#xff08;JVM&#xff09;中的一个组件&#xff0c;它在 JVM 的内存模型中扮演着非常…