web Component - 技术指南

打印 上一主题 下一主题

主题 1010|帖子 1010|积分 3030



什么是web Component ?

mdn 官方定义: Web Component
   Web Component 是一套不同的技术,允许你创建可重用的定制元素(它们的功能封装在你的代码之外)并且在你的 web 应用中使用它们。
  简朴来说他是一组尺度化的web技术,允许开发者来创建可重用的自定义标签,并且这些标签可以在不同的web应用中使用,并且可以封装内部逻辑和样式避免与使用页面的其他部分发生辩论。
Web Component主要有以下3个规范构成:


  • Custom element(自定义元素):自定义标签以及行为
  • Shadow DOM(影子 DOM):  提供DOM树与页面别的部分隔离的方法,确保样式不会泄漏到全局。
  • HTML template(HTML 模板): 用于定义可重复使用的 HTML 片断,这些片断在初始加载时不会被渲染,但可以在必要时插入文档
Web Components 解决了什么问题?

  • 可重用性:开发者可以创建一次组件并在多个项目中重复使用,减少了代码冗余,提高了开发效率。
  • 封装性:使用 Shadow DOM 封装样式和逻辑,确保组件内部的样式和脚本不会影响页面的其他部分,反之亦然。这有助于构建更稳定、更易于维护的应用步调。
  • 互操纵性:Web Components 是基于尺度的,因此可以在不同的框架和库之间无缝工作。无论你使用的是 React、Vue 还是纯 JavaScript,都可以轻松集成 Web Components。
  • 模块化:组件化的开发方式使得代码更加模块化,便于团队协作和代码管理。每个组件可以独立开发、测试和摆设。
  • 简化前端开发:Web Components 提供了一种简朴而强大的方法来构建复杂的用户界面,低落了前端开发的复杂度,尤其是对于大型应用。
实现 Web Components ?

通过Web Component实现一个自定义元素,通常必要一下5步调:
   步调一: 创建一个类或函数来指定 web 组件的功能,
  步调二:使用 CustomElementRegistry.define() 方法注册你的新自定义元素。
  步调三:使用 Element.attachShadow() 方法将一个 shadow DOM 附加到自定义元素上,可以根据需求是否添加。
  步调四:使用 <template> 和 <slot> 定义一个 HTML 模板。可以根据需求是否定义。
  步调五:页面中使用。uabn
  使用自定义元素:

自定义元素类型:


  • 自定义内置元素:继承自尺度的HTML元素,如HTMLImageElement、 HTMLParagraphElement,已经实现了尺度元素的行为。
  • 独立自定义元素: 继承HTML元素基类HTMLElement, 必须从头实现行为。
实现:以独立自定义元素为案例:(在构造函数中不能检查元素的属性或子元素,也不应添加新的属性或子元素 )构造函数如下
  1. // 自定义内置
  2. class WordCount extends HTMLParagraphElement {
  3.   constructor() {
  4.     super();
  5.   }
  6.   // 此处编写元素功能
  7. }
  8. // 独立自定义元素
  9. class PopupInfo extends HTMLElement {
  10.   constructor() {
  11.     super();
  12.   }
  13.   // 声明周期回调
  14.   connectedCallback() {
  15.     console.log("自定义元素添加至页面。");
  16.   }
  17.   disconnectedCallback() {
  18.     console.log("自定义元素从页面中移除。");
  19.   }
  20.   adoptedCallback() {
  21.     console.log("自定义元素移动至新页面。");
  22.   }
  23.   attributeChangedCallback(name, oldValue, newValue) {
  24.     console.log(`属性 ${name} 已变更。`);
  25.   }
  26. }
复制代码
注册:使用Window.customElements 的 define() 方法注册自定义元素, 方法参数如下:


  • name: 元素名称, 定名必须小写字母开头包含一个连字符
  • constructor: 自定义元素的构造函数
  • options: 仅对自定义内置元素生效,设置要拓展的元素
自定义内置元素注册和使用:
  1. // 注册:
  2. customElements.define("word-count", WordCount, { extends: "p" });
  3. // 使用:作为is属性的值
  4. <p is="word-count"></p>
复制代码
独立自定义元素注册和使用:
  1. // 注册:
  2. customElements.define("popup-info", PopupInfo);
  3. // 使用:
  4. <popup-info>
  5.   <!-- 元素的内容 -->
  6. </popup-info>
复制代码
相应属性变革:与内置元素一样, 自定义元素可以使用HTML来设置元素的行为, 为此可以添加如下属性:


  • observedAttributes:静态属性,包含变更关照的全部属性数组。
  • attributeChangedCallback():生命周期回调实现。(此方法在observedAttributes属性变动时调用)
例如: 观察size属性,并在变革时记录新旧值。
  1. // 为这个元素创建类
  2. class MyCustomElement extends HTMLElement {
  3.   static observedAttributes = ["size"];
  4.   constructor() {
  5.     super();
  6.   }
  7.   attributeChangedCallback(name, oldValue, newValue) {
  8.     console.log(`属性 ${name} 已由 ${oldValue} 变更为 ${newValue}。`);
  9.   }
  10. }
  11. customElements.define("my-custom-element", MyCustomElement);
复制代码
请留意,假如元素的 HTML 声明包含一个被观察的属性,那么在属性被初始化后,attributeChangedCallback() 将在元素的声明首次剖析时被调用。
使用影子DOM: 

   影子 DOM(Shadow DOM)允许你将一个 DOM 树附加到一个元素上,并且使该树的内部对于在页面中运行的 JavaScript 和 CSS 是隐蔽的。在其之下你可以用与普通 DOM 相同的方式附加任何元素
  

1、创建:调用影子宿主DOM上的 attachShadow() 来创建影子 DOM
        参数说明:{mode: "open"}: 页面中可通过影子宿主的 shadowRoot 属性访问影子 DOM 的内部,假如不盼望粉碎影子 DOM 封装,可设置{mode: "closed"} 
  1. const host = document.querySelector("#host");
  2. const shadow = host.attachShadow({ mode: "open" });
  3. const span = document.createElement("span");
  4. span.textContent = "I'm in the shadow DOM";
  5. shadow.appendChild(span);
复制代码
  页面展示看起来是如许

2、CSS样式应用:


  • 编程式:构建 CSSStyleSheet 附加到影子根。
  • 声明式:在template声明中添加style元素
编程式实现:1.创建一个空的CSSStyleSheet对象,2.使用replace()/replaceSync()设置内容,3.通过ShadowRoot.adoptedStyleSheets来添加到影子根:,
  1. const sheet = new CSSStyleSheet();
  2. sheet.replaceSync("span { color: red; border: 2px dotted black;}");
  3. const host = document.querySelector("#host");
  4. const shadow = host.attachShadow({ mode: "open" });
  5. shadow.adoptedStyleSheets = [sheet];
  6. const span = document.createElement("span");
  7. span.textContent = "I'm in the shadow DOM";
  8. shadow.appendChild(span);
复制代码
声明式实现:1.创建template,并添加style标签和样式内容,2.创建影子dom,并将template的内容添加到影子Dom
  1. <template id="my-element">
  2.   <style>
  3.     span {
  4.       color: red;
  5.       border: 2px dotted black;
  6.     }
  7.   </style>
  8.   <span>I'm in the shadow DOM</span>
  9. </template>
  10. <div id="host"></div>
  11. // 创建影子 DOM 并将 <template> 的内容添加到其中:
  12. const host = document.querySelector("#host");
  13. const shadow = host.attachShadow({ mode: "open" });
  14. const template = document.getElementById("my-element");
  15. shadow.appendChild(template.content);
复制代码
以上两种方式使用选择推荐:
编程式:样式表必要与多个dom树共享时推荐使用。
声明式:必要较少的样式并且不必要在不同组件之间共享样式的时候
3. 影子DOM和自定义元素:
   假如没有影子DOM提供封装,自定义元素将无法使用,页面上运行的其他js或css,可能无意间粉碎自定义元素的行为或结构。
  自定义元素被实现为一个类,它可以继承内置 HTML 元素。通常,自定义元素本身是一个影子宿主,该元素在其根节点下创建多个元素,以提供元素的内部实现。
  例如: 创建自定义元素,仅渲染一个实心颜色圆形。
  1. class FilledCircle extends HTMLElement {
  2.   constructor() {
  3.     super();
  4.   }
  5.   connectedCallback() {
  6.     // 创建一个影子根
  7.     // 自定义元素自身是影子宿主
  8.     const shadow = this.attachShadow({ mode: "open" });
  9.     // 创建内部实现
  10.     const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  11.     const circle = document.createElementNS(
  12.       "http://www.w3.org/2000/svg",
  13.       "circle",
  14.     );
  15.     circle.setAttribute("cx", "50");
  16.     circle.setAttribute("cy", "50");
  17.     circle.setAttribute("r", "50");
  18.     circle.setAttribute("fill", this.getAttribute("color"));
  19.     svg.appendChild(circle);
  20.     shadow.appendChild(svg);
  21.   }
  22. }
  23. customElements.define("filled-circle", FilledCircle);
复制代码


使用模版和插槽:

怎样使用<template>和<slot>元素创建一个机动添补web组件的影子DOM的模版。
   当你必须在网页上复用相同的标记结构时,使用某种模板而不是一遍又一遍地重复相同的结构是有意义的。以前也可以实现这一点,但 HTML <template> 元素使得这个过程更加简朴。此元素及其内容不会在 DOM 中渲染,但仍可使用 JavaScript 引用它。
  1.使用模版:(相较于原生创建dom追加元素更便捷,并且复用性高)
  1. customElements.define(
  2.   "my-paragraph",
  3.   class extends HTMLElement {
  4.     constructor() {
  5.       super();
  6.       let template = document.getElementById("my-paragraph");
  7.       let templateContent = template.content;
  8.       const shadowRoot = this.attachShadow({ mode: "open" });
  9.       shadowRoot.appendChild(templateContent.cloneNode(true));
  10.     }
  11.   },
  12. );
复制代码
2. 使用插槽:使用slot通过声明式语法在实例中展示不同文本。
模版改造:
  1. <template id="my-paragraph">
  2.   <p><slot name="my-text">我的默认文本</slot></p>
  3. </template>
复制代码
使用:
  1. <my-paragraph>
  2.   <span slot="my-text">让我们使用一些不同的文本!</span>
  3. </my-paragraph>
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金歌

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表