Web Components使用(一)

news/2024/5/16 5:00:27

在使用Web Components之前,我们先看看上一篇文章Web Components简介,其中提到了相关的接口、属性和方法。
正是这些接口、属性和方法才实现了Web Components的主要技术:Custom elements(自定义元素)、Shadow DOM(影子DOM)、HTML templates(HTML模板)。
由于并不是所有的接口以及接口所包含的方法都会被用到,所以我们从实际的案例出发,逐步了解Web Components的使用。

需求1:创建一个基础的组件,包含一个输入框,和一个button。

mian.js

class SearchInput extends HTMLElement {constructor() {super();// 创建一个 shadow rootlet shadow = this.attachShadow({mode: 'open'});const input = document.createElement('input');input.setAttribute('type', 'text');input.setAttribute('class', 'input-vlaue');const button = document.createElement('input');button.setAttribute('type', 'button');button.setAttribute('value', 'Search');// 创建一些 CSS,并应用到 shadow dom上let style = document.createElement('style');style.textContent=".input-vlaue{margin:5px; color:red;}";shadow.append(input);shadow.append(button);shadow.append(style);}
}// declare var customElements: CustomElementRegistry;
customElements.define('search-input', SearchInput);

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./main.js"></script>
</head>
<body><search-input></search-input><search-input></search-input><search-input></search-input>
</body>
</html>

运行结果
这样子,一个input + button的组件就实现了。这里用到的技术有Custom elements(自定义元素)、Shadow DOM(影子DOM)。

使用Shadow DOM的好处:Shadow DOM 内部的元素始终不会影响到它外部的元素

**要注意的是,不是每一种类型的元素都可以附加到shadow root(影子根)下面。**出于安全考虑,一些元素不能使用 shadow DOM(例如<a>),以及许多其他的元素。

Element.attachShadow() 方法给指定的元素挂载一个Shadow DOM,并且返回对 ShadowRoot 的引用。具体方法:创建一个ShadowRoot并返回它:

attachShadow(init: ShadowRootInit): ShadowRoot;

attachShadow()的参数是一个对象,里面包含两个属性,mode和delegatesFocus。

mode:可以是open/closed。
  • open:shadow root元素可以从js外部访问根节点
  • closed:拒绝从js外部访问关闭的shadow root节点
delegatesFocus 焦点委托

一个布尔值, 当设置为 true 时, 指定减轻自定义元素的聚焦性能问题行为.
当shadow DOM中不可聚焦的部分被点击时, 让第一个可聚焦的部分成为焦点, 并且shadow host(影子主机)将提供所有可用的 :focus 样式.

使用Custom elements(自定义元素)的好处:语义化,简单明了。
customElements.define(‘search-input’, SearchInput)实现了CustomElementRegistry接口,无返回值:
interface CustomElementRegistry {define(name: string, constructor: CustomElementConstructor, options?: ElementDefinitionOptions): void;get(name: string): any;upgrade(root: Node): void;whenDefined(name: string): Promise<void>;
}
需求2:可是真正的组件不仅仅有显示的功能,还需要绑定一些事件,例如上面的例子,点击了如何触发search事件呢?
核心:element.addEventListener()

代码示例(index.html不变):

class SearchInput extends HTMLElement {constructor() {super();// 创建一个 shadow rootlet shadow = this.attachShadow({mode: 'open'});const input = document.createElement('input');input.setAttribute('type', 'text');input.setAttribute('class', 'input-vlaue');const button = document.createElement('input');button.setAttribute('type', 'button');button.setAttribute('value', 'Search');const text = document.createElement('p');// 创建一些 CSS,并应用到 shadow dom上let style = document.createElement('style');style.textContent=".input-vlaue{margin:5px; color:red;}";shadow.append(input);shadow.append(button);shadow.append(text);shadow.append(style);button.addEventListener('click', e => {text.textContent = '按钮被点击了~'});}
}// declare var customElements: CustomElementRegistry;
customElements.define('search-input', SearchInput);

需求3:我们知道,像react、vue都有组件自身的状态管理,和利用Props进行数据传递,那么,在web components中是怎么实现的呢?
核心:this.getAttribute(props),class内部属性,生命周期

main.js

class SearchInput extends HTMLElement {constructor() {super();this.state = { count:0 };// 创建一个 shadow rootlet shadow = this.attachShadow({mode: 'open'});const input = document.createElement('input');input.setAttribute('type', 'text');input.setAttribute('class', 'input-value');const button = document.createElement('input');button.setAttribute('type', 'button');button.setAttribute('value', 'Search');const text = document.createElement('p');// 创建一些 CSS,并应用到 shadow dom上let style = document.createElement('style');style.textContent=".input-vlaue{margin:5px; color:red;}";shadow.append(input);shadow.append(button);shadow.append(text);shadow.append(style);button.addEventListener('click', e => {this.state.count++;text.textContent = `按钮被点击了${this.state.count}次。`});}connectedCallback () {const defaultValue = this.getAttribute('defaultValue');const input = this.shadowRoot.querySelector('.input-value');input.value = defaultValue;}
}// declare var customElements: CustomElementRegistry;
customElements.define('search-input', SearchInput);

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./main.js"></script>
</head>
<body><search-input defaultValue="input1"></search-input><search-input defaultValue="input2"></search-input><search-input defaultValue="input3"></search-input>
</body>
</html>

运行结果

到此,我们已经了解了利用Web Components创建一个组件,如何触发组件的事件,如何利用props向组件内部传递数据以及组件内部的状态管理。

目前来看缺乏的就是组件间的通信了,目前还没发现有类似react、vue的组件间通信的方法,不过我们可以利用localStorage,StorageEvent间接的发生组件间的通信、界面渲染。

如果文章能够对您有所帮助,我便感到十分荣幸。如若文章能被您点赞,那便是万分荣幸。


http://www.mrgr.cn/p/70338367

相关文章

百度智能云千帆,产业创新新引擎

本文整理自 3 月 21 日百度副总裁谢广军的主题演讲《百度智能云千帆&#xff0c;产业创新新引擎》。 各位领导、来宾、媒体朋友们&#xff0c;大家上午好。很高兴今天在石景山首钢园&#xff0c;和大家一起沟通和探讨大模型的发展趋势&#xff0c;以及百度最近一段时间的思考和…

2.7、创建列表(List)

概述 列表是一种复杂的容器&#xff0c;当列表项达到一定数量&#xff0c;内容超过屏幕大小时&#xff0c;可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集&#xff0c;例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求&#xff08;如通讯录、…

数据可视化是如何与智慧交通相结合的?

在当今社会,数据已成为信息时代的关键资源,而数据可视化则是将这些庞杂的数据转换为易于理解和分析的图形和图表的过程。随着城市化进程的加快,交通拥堵、安全管理、环境监测等问题日益凸显,智慧交通系统的构建成为了解决这些问题的关键,而数据可视化在这一过程中发挥了不…

Web Audio API 第3章 音量和响度

此章介绍的科普物理声音知识相当有用,编程的反而涉及的少音量和响度Loudness 响度 注:根据《韦氏词典》,响度是“一种声音的属性,它决定了所产生的听觉感觉的大小,主要取决于所涉及声波的振幅。”这意味着响度取决于你大脑中感知到的声音。而是声音对你来说有多大。这是主…

在 kubernetes 环境下如何优雅扩缩容 Pulsar

背景 在整个大环境的降本增效的熏陶下,我们也不得不做好应对方案。 根据对线上流量、存储以及系统资源的占用,发现我们的 Pulsar 集群有许多的冗余,所以考虑进行缩容从而减少资源浪费,最终也能省一些费用。 不过在缩容之前很有必要先聊聊扩容,Pulsar 一开始就是存算分离的…

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…

深度学习故障诊断实战 | 数据预处理之创建Dataloader数据集

前言 本期给大家分享介绍如何用Dataloader创建数据集 背景 示例代码 from torch import nn import torch import os import numpy as np import pandas as pd import matplotlib.pyplot as plt import time import torch.functional as F from sklearn.manifold import TSNE…

Sysbench安装与使用

Sysbench Sysbench安装curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash sudo apt -y install sysbench sysbench --versionSysbench使用 内存测试 查看内存帮助信息 sysbench memory help # 查看内存帮助信息 sysbench 1.0…

为什么Python不适合写游戏?

知乎上有热门个问题&#xff1a;Python 能写游戏吗&#xff1f;有没有什么开源项目&#xff1f; Python可以开发游戏&#xff0c;但不是好的选择 Python作为脚本语言&#xff0c;一般很少用来开发游戏&#xff0c;但也有不少大型游戏有Python的身影&#xff0c;比如&#xff1…

数据可视化是怎样帮助网络安全建设的?

在当今数字化时代,网络安全已成为各大企业乃至国家安全的重要组成部分。随着网络攻击的日益复杂和隐蔽,传统的网络安全防护措施已难以满足需求,急需新型的解决方案以增强网络防护能力。数据可视化技术,作为一种将复杂数据转换为图形或图像表示的方法,正在成为提升网络安全…

Java八股文(JVM)

Java八股文のJVM JVM JVM 什么是Java虚拟机&#xff08;JVM&#xff09;&#xff1f; Java虚拟机是一个运行Java字节码的虚拟机。 它负责将Java程序翻译成机器代码并执行。 JVM的主要组成部分是什么&#xff1f; JVM包括以下组件&#xff1a; ● 类加载器&#xff08;ClassLoa…

Sentinel 对分布式服务进行流量控制

可以下载sentinel的jar包,用java -jar命令直接启动默认端口就是8080,这里随便写一下演示,其他修改还是直接看Sentinel网站吧 java -jar -Dserver.port=8080 sentinel的jar包名.jar对需要进行流量控制的服务进行依赖导入(这个依赖直接在父工程引入似乎无效,不知为何) <…

pod 入门

pod 入门 入门级的放通网络 我们使用 nginx 创建的pod,必须要能本地访问它才行,在不引入复杂的网络环境的前提下,我们可以通过映射端口或者映射本机网络的方式进行访问。 apiVersion: v1 kind: Pod metadata:name: web01labels:app: nginxversion: "1.24"namespac…

verilog设计-cdc:多比特信号跨时钟域(DMUX)

一、前言 多比特一般为数据&#xff0c;其在跨时钟域传输的过程中有多种处理方式&#xff0c;比如DMUX&#xff0c;异步FIFO&#xff0c;双口RAM&#xff0c;握手处理。本文介绍通过DMUX的方式传输多比特信号。 二、DMUX同步跨时钟域数据 dmux表示数据分配器&#xff0c;该方…

由浅到深认识Java语言(25):正则表达式

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

殊荣双至,天翼云边缘计算再获两项大奖!

近日,全球边缘计算大会北京站在新世界大酒店成功召开。大会公布了“2023金边奖”评选结果,天翼云斩获“最佳智能边缘云服务商”“最佳边缘安全加速平台”两项大奖。天翼云边缘计算产品专家熊瑶、天翼云边缘安全产品专家杜茜参加会议并分别发表演讲,分享了天翼云边缘计算发展…

多所大学在用的网速测试网页工具librespeed/speedtest精简版

亲测比较准&#xff0c;所以精简自用并分享。 https://github.com/librespeed/speedtest/ 精简到15KB版本&#xff1a;https://download.csdn.net/download/YUJIANYUE/89049070

echarts 水球图

本文章出自: 作者:你不知道的巨蟹 文章:vue中如何使用基于 echarts 的 echarts-liquidfill 插件开发水球图前言 echarts4 官网:https://echarts.apache.org/v4/zh/option.html#series-scatter.coordinateSystemecharts5 官网:https://echarts.apache.org/echarts-liquidfi…

# Apache SeaTunnel 究竟是什么?

作者 | Shawn Gordon 翻译 | Debra Chen 原文链接 | What the Heck is Apache SeaTunnel? 我在2023年初开始注意到Apache SeaTunnel的相关讨论,一直低调地关注着。该项目始于2017年,最初名为Waterdrop,在Apache DolphinScheduler的创建者的贡献下发展起来,后者支持SeaTunn…

MybatisPlus多参数分页查询,黑马程序员SpringBoot3+Vue3教程第22集使用MP代替pagehelper

前言: 视频来源1:黑马程序员SpringBoot3+Vue3全套视频教程,springboot+vue企业级全栈开发从基础、实战到面试一套通关 视频来源2:黑马程序员最新MybatisPlus全套视频教程,4小时快速精通mybatis-plus框架 创作理由:网上MP实现分页查询功能的帖子易读性太差,具体实现看下面…