关于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;强大的算力往往是实现高效应用…

【机器学习】聚类算法原理详解

聚类算法 性能度量&#xff1a; 外部指标 jaccard系数&#xff08;简称JC&#xff09;FM指数&#xff08;简称FMI&#xff09;Rand指数&#xff08;简称RI&#xff09; 内部指标 DB指数&#xff08;简称DBI&#xff09;Dunn指数&#xff08;简称DI&#xff09; 距离计算&am…

前端性能优化深入解析:提升用户体验的几个关键点

文章目录 前言一、代码分割与动态导入二、图片和脚本的懒加载三、缓存策略四、如何根据项目特点选择合适的前端性能优化策略&#xff1f;结语 前言 在当今的互联网环境中&#xff0c;网页加载速度直接影响到用户的满意度和留存率。因此&#xff0c;前端性能优化对于提高用户体…

系统架构设计师论文

资源库&#xff1a;https://blog.csdn.net/weixin_43905586/article/details/118719986 2019年 2019年下半年试题二&#xff1a;论软件系统架构评估及其应用 2012年 2012年下半年试题一&#xff1a;论基于架构的软件设计方法及应用

用 Android Studio 从零开发一个多功能计算器应用

简介 计算器是每个学习 Android 开发者必经的经典项目之一。本篇文章将带你创建一个功能更强大的计算器应用&#xff0c;支持基本的加减乘除运算、带小数点的输入以及更多操作符功能。通过这个项目&#xff0c;你将全面掌握 Android 的布局设计、事件处理和逻辑实现技巧。 一、…

【代码随想录day33】【C++复健】62.不同路径;63. 不同路径 II;343. 整数拆分;96.不同的二叉搜索树

感觉dp的题真的很适合背&#xff0c;当然不是死记硬背&#xff0c;而是当做一种模板题&#xff0c;出来一道新的题就往模板题上面去靠&#xff0c;如果套对模板的话剩下的事情其实就简单了。所以只要看一遍解法知道大致思路其实就够了&#xff0c;毕竟大部分dp的代码也不算难写…

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…

PGMP-练DAY26

1. Which of the following items are key elements of the program charter?以下哪些项目是项目集章程的关键要素&#xff1f; A.Scope, assumptions,constraints,goals and objectives, timing, key stakeholders.范围、假设、约束、目标和目的、时间安排、主要利益相关者 …

Spark_写ORALCE:ORA-01426 numeric overflow 问题解决

问题 是这样的&#xff0c;20241118&#xff0c;我spark程序写Oracle时候&#xff0c;关联完HBase数据后&#xff0c;在写入ORACLE中&#xff0c;遇到了这个bug&#xff0c; 数据入到一半&#xff0c;每次都报错ORA-01426 numeric overflow&#xff0c;具体呢&#xff0c;也不告…

初识Linux · 信号处理 · 续

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

流量模型 -20241118

流量模型 个体的注意力注意力提升销量&#xff0c;转化为直接收益&#xff0c;同时提升品牌价值购物平台的出现使注意力变现变得简单&#xff0c;开拓了注意力的的使用方式&#xff0c;使其分散使用转变为集中使用各个视频&#xff0c;直播平台集中注意力&#xff0c;使得流量…

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

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