当前位置: 首页 > news >正文

Web Components使用(一)

在使用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间接的发生组件间的通信、界面渲染。

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

相关文章:

  • 【ZZULIOJ】1014: 求三角形的面积(Java)
  • 网络工程师实验命令(华为数通HCIA)
  • 机器学习_集成学习_梯度提升_回归_决策树_XGBoost相关概念
  • 初识C++之命名空间(namespace)
  • Java中如何恰当的表达“继承”与“扩展”的语义?
  • docker 部署 gitlab-ce 16.9.1
  • vim分屏命令
  • 包子凑数(蓝桥杯,闫氏DP分析法)
  • C#-COM组件
  • unity双层滑动实现
  • Java八股文(JVM)
  • 【Go】结构体中Tag标识
  • C语言复习 -- 字符串
  • Qt_day4:2024/3/25
  • NetCore itext7 创建、编辑PDF插入表格、图片、文字(三)
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • extract-text-webpack-plugin用法
  • HTTP 简介
  • Java 内存分配及垃圾回收机制初探
  • js如何打印object对象
  • nodejs:开发并发布一个nodejs包
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • 彻底搞懂浏览器Event-loop
  • 从零搭建Koa2 Server
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 前端js -- this指向总结。
  • 深度解析利用ES6进行Promise封装总结
  • 使用 QuickBI 搭建酷炫可视化分析
  • 听说你叫Java(二)–Servlet请求
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 我看到的前端
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​ArcGIS Pro 如何批量删除字段
  • ​马来语翻译中文去哪比较好?
  • #define、const、typedef的差别
  • (07)Hive——窗口函数详解
  • (42)STM32——LCD显示屏实验笔记
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (二)windows配置JDK环境
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (分布式缓存)Redis持久化
  • (汇总)os模块以及shutil模块对文件的操作
  • (论文阅读11/100)Fast R-CNN
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET 解决重复提交问题
  • .net 托管代码与非托管代码
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET的数据绑定